fix GIO_LAUNCHED_DESKTOP_FILE_PID (#30)

* fix: set GIO_LAUNCHED_DESKTOP_FILE_PID

To set GIO_LAUNCHED_DESKTOP_FILE_PID, we have to manually fork and
exec, as QT determined the environ use to execvp, before running
childModifyer.

After use bare fork and exec, we have to wait for dead child processes.
Otherwise there will be zombies.

Signed-off-by: black-desk <me@black-desk.cn>

* fix: X-Deepin-CreatedBy is key not value

-

Signed-off-by: black-desk <me@black-desk.cn>

---------

Signed-off-by: black-desk <me@black-desk.cn>
This commit is contained in:
black-desk 2023-04-22 17:29:10 +08:00 committed by GitHub
parent 63d9f4ed57
commit dc617910fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 27 deletions

View File

@ -247,8 +247,8 @@ bool Launcher::requestSendToDesktop(QString appId)
// 创建桌面快捷方式文件
DesktopInfo dinfo(itemsMap[appId].info.path.toStdString());
dinfo.getDesktopFile()->setKey(MainSection, dbusService.toStdString(), "X-Deepin-CreatedBy");
dinfo.getDesktopFile()->setKey(MainSection, appId.toStdString(), "X-Deepin-AppID");
dinfo.getDesktopFile()->setKey(MainSection, "X-Deepin-CreatedBy", dbusService.toStdString());
dinfo.getDesktopFile()->setKey(MainSection, "X-Deepin-AppID", appId.toStdString());
if (!dinfo.getDesktopFile()->saveToFile(filePath.toStdString()))
return false;

View File

@ -12,6 +12,7 @@
#include "meminfo.h"
#include "../../service/impl/application_manager.h"
#include <sys/wait.h>
#include <wordexp.h>
#include <QFileSystemWatcher>
@ -37,12 +38,25 @@ StartManager::StartManager(QObject *parent)
, m_autostartFiles(getAutostartList())
, m_isDBusCalled(false)
{
waitForDeadChild();
loadSysMemLimitConfig();
getDesktopToAutostartMap();
listenAutostartFileEvents();
startAutostartProgram();
}
static void sig_child(int signo)
{
int stat;
int pid;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0);
}
void StartManager::waitForDeadChild()
{
signal(SIGCHLD, sig_child);
}
bool StartManager::addAutostart(const QString &desktop)
{
setIsDBusCalled(true);
@ -369,24 +383,26 @@ bool StartManager::doLaunchAppWithOptions(QString desktopFile, uint32_t timestam
bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp, QStringList files)
{
QProcess process;
QProcess process; // NOTE(black_desk): this QProcess not used to start, we
// have to manually fork and exec to set
// GIO_LAUNCHED_DESKTOP_FILE_PID.
QStringList cmdPrefixesEnvs;
QStringList envs;
QProcessEnvironment envs = QProcessEnvironment::systemEnvironment();
QString appId(QString::fromStdString(info->getId()));
bool useProxy = shouldUseProxy(appId);
for (QString var : QProcess::systemEnvironment()) {
if (useProxy && (var.startsWith("auto_proxy")
|| var.startsWith("http_proxy")
|| var.startsWith("https_proxy")
|| var.startsWith("ftp_proxy")
|| var.startsWith("all_proxy")
|| var.startsWith("SOCKS_SERVER")
|| var.startsWith("no_proxy"))) {
continue;
}
envs << var;
if (useProxy) {
envs.remove("auto_proxy");
envs.remove("AUTO_PROXY");
envs.remove("http_proxy");
envs.remove("HTTP_PROXY");
envs.remove("https_proxy");
envs.remove("HTTPS_PROXY");
envs.remove("ftp_proxy");
envs.remove("FTP_PROXY");
envs.remove("SOCKS_SERVER");
envs.remove("no_proxy");
envs.remove("NO_PROXY");
}
// FIXME: Don't using env to control the window scale factor, this function
@ -403,12 +419,10 @@ bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp
double scale = ret.isValid() ? ret.value() : 1.0;
scale = scale > 0 ? scale : 1;
const QString scaleStr = QString::number(scale, 'f', -1);
envs << "DEEPIN_WINE_SCALE=" + scaleStr;
envs.insert("DEEPIN_WINE_SCALE", scaleStr);
}
}
envs << cmdPrefixesEnvs;
QStringList exeArgs;
auto stdCmdLine = cmdLine.toStdString();
@ -438,8 +452,8 @@ bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp
QString exec = exeArgs[0];
exeArgs.removeAt(0);
qDebug() << "Launching app, desktop: " << QString::fromStdString(info->getFileName()) << " exec: " << exec
<< " args: " << exeArgs << " useProxy:" << useProxy << "appid:" << appId << "envs:" << envs;
qDebug() << "Launching app, desktop:" << QString::fromStdString(info->getFileName()) << "exec:" << exec
<< "args:" << exeArgs << "useProxy:" << useProxy << "appid:" << appId << "envs:" << envs.toStringList();
process.setProgram(exec);
process.setArguments(exeArgs);
@ -447,17 +461,36 @@ bool StartManager::launch(DesktopInfo *info, QString cmdLine, uint32_t timestamp
// NOTE(black_desk): This have to be done after load system environment.
// Set same env twice in qt make the first one gone.
envs << QString("GIO_LAUNCHED_DESKTOP_FILE=") +
QString::fromStdString(info->getDesktopFile()->getFilePath());
envs.insert("GIO_LAUNCHED_DESKTOP_FILE", QString::fromStdString(info->getDesktopFile()->getFilePath()));
process.setEnvironment(envs);
qint64 pid = 0;
if (process.startDetached(&pid)) {
qint64 pid = fork();
if (pid == 0) {
envs.insert("GIO_LAUNCHED_DESKTOP_FILE_PID", QByteArray::number(getpid()).constData());
auto argList = process.arguments();
char const * args[argList.length() + 1];
std::transform(argList.constBegin(), argList.constEnd(), args, [](const QString& str){
auto byte = new QByteArray;
*byte = str.toUtf8();
auto tmp_buf = byte->data();
return tmp_buf;
});
args[process.arguments().length()] = 0;
auto envStringList = envs.toStringList();
char const * envs[envStringList.length() + 1];
std::transform(envStringList.constBegin(), envStringList.constEnd(), envs, [](const QString& str){
auto byte = new QByteArray;
*byte = str.toUtf8();
auto tmp_buf = byte->data();
return tmp_buf;
});
envs[envStringList.length()] = 0;
execvpe(process.program().toLocal8Bit().constData(), (char**)args, (char**)envs);
exit(-1);
} else {
if (useProxy) {
qDebug() << "Launch the process[" << pid << "] by app proxy.";
dbusHandler->addProxyProc(pid);
}
return true;
}
return false;

View File

@ -40,6 +40,7 @@ public Q_SLOTS:
void onAutoStartupPathChange(const QString &dirPath);
private:
void waitForDeadChild();
bool setAutostart(const QString &fileName, const bool value);
bool doLaunchAppWithOptions(const QString &desktopFile);
bool doLaunchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QVariantMap options);