forked from qt-creator/qt-creator
use temp file to pass env on unix as well
the linux command line can be 32k long ... which might still be not enough. well, in fact, it just makes the 'ps' output unreadable.
This commit is contained in:
@@ -43,10 +43,13 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QWinEventNotifier;
|
class QWinEventNotifier;
|
||||||
class QTemporaryFile;
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QTemporaryFile;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
@@ -102,12 +105,12 @@ private:
|
|||||||
QProcess::ExitStatus m_appStatus;
|
QProcess::ExitStatus m_appStatus;
|
||||||
QLocalServer m_stubServer;
|
QLocalServer m_stubServer;
|
||||||
QLocalSocket *m_stubSocket;
|
QLocalSocket *m_stubSocket;
|
||||||
|
QTemporaryFile *m_tempFile;
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
PROCESS_INFORMATION *m_pid;
|
PROCESS_INFORMATION *m_pid;
|
||||||
HANDLE m_hInferior;
|
HANDLE m_hInferior;
|
||||||
QWinEventNotifier *inferiorFinishedNotifier;
|
QWinEventNotifier *inferiorFinishedNotifier;
|
||||||
QWinEventNotifier *processFinishedNotifier;
|
QWinEventNotifier *processFinishedNotifier;
|
||||||
QTemporaryFile *m_tempFile;
|
|
||||||
#else
|
#else
|
||||||
QProcess m_process;
|
QProcess m_process;
|
||||||
QByteArray m_stubServerDir;
|
QByteArray m_stubServerDir;
|
||||||
|
@@ -72,6 +72,22 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!environment().isEmpty()) {
|
||||||
|
m_tempFile = new QTemporaryFile();
|
||||||
|
if (!m_tempFile->open()) {
|
||||||
|
stubServerShutdown();
|
||||||
|
emit processError(tr("Cannot create temp file: %1").arg(m_tempFile->errorString()));
|
||||||
|
delete m_tempFile;
|
||||||
|
m_tempFile = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach (const QString &var, environment()) {
|
||||||
|
m_tempFile->write(var.toLocal8Bit());
|
||||||
|
m_tempFile->write("", 1);
|
||||||
|
}
|
||||||
|
m_tempFile->flush();
|
||||||
|
}
|
||||||
|
|
||||||
QStringList xtermArgs;
|
QStringList xtermArgs;
|
||||||
xtermArgs << "-e"
|
xtermArgs << "-e"
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
@@ -82,13 +98,16 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
|
|||||||
<< (m_debug ? "debug" : "exec")
|
<< (m_debug ? "debug" : "exec")
|
||||||
<< m_stubServer.fullServerName()
|
<< m_stubServer.fullServerName()
|
||||||
<< tr("Press <RETURN> to close this window...")
|
<< tr("Press <RETURN> to close this window...")
|
||||||
<< workingDirectory() << environment() << ""
|
<< workingDirectory()
|
||||||
|
<< (m_tempFile ? m_tempFile->fileName() : 0)
|
||||||
<< program << args;
|
<< program << args;
|
||||||
|
|
||||||
m_process.start(QLatin1String("xterm"), xtermArgs);
|
m_process.start(QLatin1String("xterm"), xtermArgs);
|
||||||
if (!m_process.waitForStarted()) {
|
if (!m_process.waitForStarted()) {
|
||||||
stubServerShutdown();
|
stubServerShutdown();
|
||||||
emit processError(tr("Cannot start console emulator xterm."));
|
emit processError(tr("Cannot start console emulator xterm."));
|
||||||
|
delete m_tempFile;
|
||||||
|
m_tempFile = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_executable = program;
|
m_executable = program;
|
||||||
@@ -173,6 +192,10 @@ void ConsoleProcess::readStubOutput()
|
|||||||
emit processError(tr("Cannot execute %1: %2")
|
emit processError(tr("Cannot execute %1: %2")
|
||||||
.arg(m_executable, errorMsg(out.mid(9).toInt())));
|
.arg(m_executable, errorMsg(out.mid(9).toInt())));
|
||||||
} else if (out.startsWith("pid ")) {
|
} else if (out.startsWith("pid ")) {
|
||||||
|
// Will not need it any more
|
||||||
|
delete m_tempFile;
|
||||||
|
m_tempFile = 0;
|
||||||
|
|
||||||
m_appPid = out.mid(4).toInt();
|
m_appPid = out.mid(4).toInt();
|
||||||
emit processStarted();
|
emit processStarted();
|
||||||
} else if (out.startsWith("exit ")) {
|
} else if (out.startsWith("exit ")) {
|
||||||
@@ -199,6 +222,8 @@ void ConsoleProcess::stubExited()
|
|||||||
if (m_stubSocket && m_stubSocket->state() == QLocalSocket::ConnectedState)
|
if (m_stubSocket && m_stubSocket->state() == QLocalSocket::ConnectedState)
|
||||||
m_stubSocket->waitForDisconnected();
|
m_stubSocket->waitForDisconnected();
|
||||||
stubServerShutdown();
|
stubServerShutdown();
|
||||||
|
delete m_tempFile;
|
||||||
|
m_tempFile = 0;
|
||||||
if (m_appPid) {
|
if (m_appPid) {
|
||||||
m_appStatus = QProcess::CrashExit;
|
m_appStatus = QProcess::CrashExit;
|
||||||
m_appCode = -1;
|
m_appCode = -1;
|
||||||
|
@@ -73,18 +73,19 @@ enum {
|
|||||||
ArgSocket,
|
ArgSocket,
|
||||||
ArgMsg,
|
ArgMsg,
|
||||||
ArgDir,
|
ArgDir,
|
||||||
ArgEnv
|
ArgEnv,
|
||||||
|
ArgExe
|
||||||
};
|
};
|
||||||
|
|
||||||
/* syntax: $0 {"run"|"debug"} <pid-socket> <continuation-msg> <workdir> <env...> "" <exe> <args...> */
|
/* syntax: $0 {"run"|"debug"} <pid-socket> <continuation-msg> <workdir> <env-file> <exe> <args...> */
|
||||||
/* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */
|
/* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int envIdx = ArgEnv;
|
|
||||||
int errNo;
|
int errNo;
|
||||||
int chldPid;
|
int chldPid;
|
||||||
int chldStatus;
|
int chldStatus;
|
||||||
int chldPipe[2];
|
int chldPipe[2];
|
||||||
|
char **env = 0;
|
||||||
struct sockaddr_un sau;
|
struct sockaddr_un sau;
|
||||||
|
|
||||||
if (argc < ArgEnv) {
|
if (argc < ArgEnv) {
|
||||||
@@ -111,6 +112,35 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*argv[ArgEnv]) {
|
||||||
|
FILE *envFd;
|
||||||
|
char *envdata, *edp;
|
||||||
|
long size;
|
||||||
|
int count;
|
||||||
|
if (!(envFd = fopen(argv[ArgEnv], "r"))) {
|
||||||
|
fprintf(stderr, "Cannot read creator env file %s: %s\n",
|
||||||
|
argv[ArgEnv], strerror(errno));
|
||||||
|
doExit(1);
|
||||||
|
}
|
||||||
|
fseek(envFd, 0, SEEK_END);
|
||||||
|
size = ftell(envFd);
|
||||||
|
rewind(envFd);
|
||||||
|
envdata = malloc(size);
|
||||||
|
if (fread(envdata, 1, size, envFd) != (size_t)size) {
|
||||||
|
perror("Failed to read env file");
|
||||||
|
doExit(1);
|
||||||
|
}
|
||||||
|
fclose(envFd);
|
||||||
|
for (count = 0, edp = envdata; edp < envdata + size; ++count)
|
||||||
|
edp += strlen(edp) + 1;
|
||||||
|
env = malloc((count + 1) * sizeof(char *));
|
||||||
|
for (count = 0, edp = envdata; edp < envdata + size; ++count) {
|
||||||
|
env[count] = edp;
|
||||||
|
edp += strlen(edp) + 1;
|
||||||
|
}
|
||||||
|
env[count] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create execution result notification pipe. */
|
/* Create execution result notification pipe. */
|
||||||
if (pipe(chldPipe)) {
|
if (pipe(chldPipe)) {
|
||||||
perror("Cannot create status pipe");
|
perror("Cannot create status pipe");
|
||||||
@@ -142,14 +172,10 @@ int main(int argc, char *argv[])
|
|||||||
ptrace(PT_TRACE_ME, 0, 0, 0);
|
ptrace(PT_TRACE_ME, 0, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (envIdx = ArgEnv; *argv[envIdx]; ++envIdx) ;
|
if (env)
|
||||||
if (envIdx != ArgEnv) {
|
environ = env;
|
||||||
argv[envIdx] = 0;
|
|
||||||
environ = argv + ArgEnv;
|
|
||||||
}
|
|
||||||
++envIdx;
|
|
||||||
|
|
||||||
execvp(argv[envIdx], argv + envIdx);
|
execvp(argv[ArgExe], argv + ArgExe);
|
||||||
/* Only expected error: no such file or direcotry, i.e. executable not found */
|
/* Only expected error: no such file or direcotry, i.e. executable not found */
|
||||||
errNo = errno;
|
errNo = errno;
|
||||||
write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */
|
write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */
|
||||||
|
Reference in New Issue
Block a user