summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libs/utils/consoleprocess.h7
-rw-r--r--src/libs/utils/consoleprocess_unix.cpp27
-rw-r--r--src/libs/utils/process_stub_unix.c46
3 files changed, 67 insertions, 13 deletions
diff --git a/src/libs/utils/consoleprocess.h b/src/libs/utils/consoleprocess.h
index 53c69c91af..821e8cb7c8 100644
--- a/src/libs/utils/consoleprocess.h
+++ b/src/libs/utils/consoleprocess.h
@@ -43,10 +43,13 @@
#include <windows.h>
QT_BEGIN_NAMESPACE
class QWinEventNotifier;
-class QTemporaryFile;
QT_END_NAMESPACE
#endif
+QT_BEGIN_NAMESPACE
+class QTemporaryFile;
+QT_END_NAMESPACE
+
namespace Core {
namespace Utils {
@@ -102,12 +105,12 @@ private:
QProcess::ExitStatus m_appStatus;
QLocalServer m_stubServer;
QLocalSocket *m_stubSocket;
+ QTemporaryFile *m_tempFile;
#ifdef Q_OS_WIN
PROCESS_INFORMATION *m_pid;
HANDLE m_hInferior;
QWinEventNotifier *inferiorFinishedNotifier;
QWinEventNotifier *processFinishedNotifier;
- QTemporaryFile *m_tempFile;
#else
QProcess m_process;
QByteArray m_stubServerDir;
diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp
index 2e20ac0c37..276d6c77f2 100644
--- a/src/libs/utils/consoleprocess_unix.cpp
+++ b/src/libs/utils/consoleprocess_unix.cpp
@@ -72,6 +72,22 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
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;
xtermArgs << "-e"
#ifdef Q_OS_MAC
@@ -82,13 +98,16 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
<< (m_debug ? "debug" : "exec")
<< m_stubServer.fullServerName()
<< tr("Press <RETURN> to close this window...")
- << workingDirectory() << environment() << ""
+ << workingDirectory()
+ << (m_tempFile ? m_tempFile->fileName() : 0)
<< program << args;
m_process.start(QLatin1String("xterm"), xtermArgs);
if (!m_process.waitForStarted()) {
stubServerShutdown();
emit processError(tr("Cannot start console emulator xterm."));
+ delete m_tempFile;
+ m_tempFile = 0;
return false;
}
m_executable = program;
@@ -173,6 +192,10 @@ void ConsoleProcess::readStubOutput()
emit processError(tr("Cannot execute %1: %2")
.arg(m_executable, errorMsg(out.mid(9).toInt())));
} else if (out.startsWith("pid ")) {
+ // Will not need it any more
+ delete m_tempFile;
+ m_tempFile = 0;
+
m_appPid = out.mid(4).toInt();
emit processStarted();
} else if (out.startsWith("exit ")) {
@@ -199,6 +222,8 @@ void ConsoleProcess::stubExited()
if (m_stubSocket && m_stubSocket->state() == QLocalSocket::ConnectedState)
m_stubSocket->waitForDisconnected();
stubServerShutdown();
+ delete m_tempFile;
+ m_tempFile = 0;
if (m_appPid) {
m_appStatus = QProcess::CrashExit;
m_appCode = -1;
diff --git a/src/libs/utils/process_stub_unix.c b/src/libs/utils/process_stub_unix.c
index 92c38bb5f0..9a31940382 100644
--- a/src/libs/utils/process_stub_unix.c
+++ b/src/libs/utils/process_stub_unix.c
@@ -73,18 +73,19 @@ enum {
ArgSocket,
ArgMsg,
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 */
int main(int argc, char *argv[])
{
- int envIdx = ArgEnv;
int errNo;
int chldPid;
int chldStatus;
int chldPipe[2];
+ char **env = 0;
struct sockaddr_un sau;
if (argc < ArgEnv) {
@@ -111,6 +112,35 @@ int main(int argc, char *argv[])
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. */
if (pipe(chldPipe)) {
perror("Cannot create status pipe");
@@ -142,14 +172,10 @@ int main(int argc, char *argv[])
ptrace(PT_TRACE_ME, 0, 0, 0);
#endif
- for (envIdx = ArgEnv; *argv[envIdx]; ++envIdx) ;
- if (envIdx != ArgEnv) {
- argv[envIdx] = 0;
- environ = argv + ArgEnv;
- }
- ++envIdx;
+ if (env)
+ environ = env;
- execvp(argv[envIdx], argv + envIdx);
+ execvp(argv[ArgExe], argv + ArgExe);
/* Only expected error: no such file or direcotry, i.e. executable not found */
errNo = errno;
write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */