From cbad53a5c86843a7102869c5b4635e8a159f563c Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Wed, 25 Jul 2012 09:56:00 +0000 Subject: [PATCH] fix auicklaunch to transport environment as well as args. fixes startup id tracking for e. SVN revision: 74380 --- legacy/elementary/ChangeLog | 6 +++ legacy/elementary/configure.ac | 16 ++++++ legacy/elementary/src/bin/quicklaunch.c | 60 +++++++++++++++++---- legacy/elementary/src/bin/run.c | 72 +++++++++++++++++++++---- 4 files changed, 132 insertions(+), 22 deletions(-) diff --git a/legacy/elementary/ChangeLog b/legacy/elementary/ChangeLog index 6bf25783c2..42a8172786 100644 --- a/legacy/elementary/ChangeLog +++ b/legacy/elementary/ChangeLog @@ -344,3 +344,9 @@ 2012-07-24 Gustavo Sverzut Barbieri (k-s) * Add elm_flip_go_to() + +2012-07-25 Carsten Haitzler (The Rasterman) + + * Fix elementary quicklaunch to transprot environment over as + well as args and cwd. + diff --git a/legacy/elementary/configure.ac b/legacy/elementary/configure.ac index a7f8e6ed5f..446e2ccb3c 100644 --- a/legacy/elementary/configure.ac +++ b/legacy/elementary/configure.ac @@ -723,6 +723,22 @@ AC_DEFINE_UNQUOTED(ELEMENTARY_BASE_DIR, "${elementary_base_dir}", "subdirectory EFL_CHECK_BUILD_EXAMPLES([enable_build_examples="yes"], [enable_build_examples="no"]) EFL_CHECK_INSTALL_EXAMPLES([enable_install_examples="yes"], [enable_install_examples="no"]) +AC_TRY_COMPILE([ +# define _GNU_SOURCE 1 +#include +], [ +extern char **environ; +], [ + AC_DEFINE(HAVE_ENVIRON, 1, [extern environ exists]) +]) + +AC_TRY_COMPILE([ +#include +], [ +clearenv(); +], [ + AC_DEFINE(HAVE_CLEARENV, 1, [extern environ exists]) +]) AC_OUTPUT([ Makefile diff --git a/legacy/elementary/src/bin/quicklaunch.c b/legacy/elementary/src/bin/quicklaunch.c index c9e6de90ba..9a318c9557 100644 --- a/legacy/elementary/src/bin/quicklaunch.c +++ b/legacy/elementary/src/bin/quicklaunch.c @@ -9,12 +9,19 @@ #include #include #include +#ifdef HAVE_ENVIRON +# define _GNU_SOURCE 1 +#endif #include #include #include #include #include +#ifdef HAVE_ENVIRON +extern char **environ; +#endif + static double restart_time = 0.0; #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path)) @@ -91,20 +98,54 @@ handle_run(int fd, unsigned long bytes) unsigned char *buf = NULL; int i; char **argv = NULL; + char **envir = NULL; char *cwd; - int argc; + int argc, envnum; + unsigned long off; buf = alloca(bytes); - if (read(fd, buf, bytes) <= 0) + if (read(fd, buf, bytes) != (int)bytes) { + CRITICAL("cannot read %i bytes of args and environment data", (int)bytes); close(fd); return; } close(fd); + argc = ((unsigned long *)(buf))[0]; - argv = (char **)(&(((unsigned long *)(buf))[1])); - for (i = 0; i < argc; i++) argv[i] = (char *)(buf + (unsigned long)argv[i]); - cwd = argv[argc - 1] + strlen(argv[argc - 1]) + 1; + envnum = ((unsigned long *)(buf))[1]; + + if (argc > 0) argv = alloca(argc * sizeof(char *)); + if (envnum > 0) envir = alloca(envnum * sizeof(char *)); + off = ((unsigned long *)(buf))[2 + argc + envnum] - sizeof(unsigned long); + cwd = (char *)(buf + off); + + if (argv) + { + for (i = 0; i < argc; i++) + { + off = ((unsigned long *)(buf))[2 + i] - sizeof(unsigned long); + argv[i] = (char *)(buf + off); + } + } + +#ifdef HAVE_ENVIRON + if (envir) + { +#ifdef HAVE_CLEARENV + clearenv(); +#else + environ = NULL; +#endif + for (i = 0; i < envnum; i++) + { + off = ((unsigned long *)(buf))[2 + argc + i] - sizeof(unsigned long); + envir[i] = (char *)(buf + off); + printf("SET ENV %s\n", envir[i]); + putenv(envir[i]); + } + } +#endif elm_quicklaunch_prepare(argc, argv); elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL); elm_quicklaunch_cleanup(); @@ -119,6 +160,7 @@ main(int argc, char **argv) struct linger lin; char buf[PATH_MAX]; struct sigaction action; + const char *disp; if (!eina_init()) { @@ -133,14 +175,10 @@ main(int argc, char **argv) _log_dom = EINA_LOG_DOMAIN_GLOBAL; } - if (!getenv("DISPLAY")) - { - CRITICAL("DISPLAY env var not set"); - exit(-1); - } + if (!(disp = getenv("DISPLAY"))) disp = "unknown"; snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i", getuid()); if (stat(buf, &st) < 0) mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR); - snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), getenv("DISPLAY")); + snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp); unlink(buf); sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) diff --git a/legacy/elementary/src/bin/run.c b/legacy/elementary/src/bin/run.c index ebd9833c2f..700bc70b0d 100644 --- a/legacy/elementary/src/bin/run.c +++ b/legacy/elementary/src/bin/run.c @@ -7,6 +7,9 @@ #include #include #include +#ifdef HAVE_ENVIRON +# define _GNU_SOURCE 1 +#endif #include #include #include @@ -14,12 +17,16 @@ # include #endif +#ifdef HAVE_ENVIRON +extern char **environ; +#endif + #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path)) int main(int argc, char **argv) { - int sock, socket_unix_len, i; + int sock, socket_unix_len, i, n; struct sockaddr_un socket_unix; char buf[PATH_MAX]; struct stat st; @@ -28,7 +35,7 @@ main(int argc, char **argv) char *disp; char *cwd; - int sargc, slen; + int sargc, slen, envnum; unsigned char *sbuf = NULL, *pos; char **sargv = NULL; @@ -38,11 +45,7 @@ main(int argc, char **argv) exit(-1); } cwd = strdup(buf); - if (!(disp = getenv("DISPLAY"))) - { - fprintf(stderr, "elementary_quicklaunch: DISPLAY env var not set\n"); - exit(-1); - } + if (!(disp = getenv("DISPLAY"))) disp = "unknown"; snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp); if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { @@ -134,25 +137,72 @@ main(int argc, char **argv) sargc = argc - 1; sargv = &(argv[1]); } - slen = sizeof(unsigned long) + sizeof(unsigned long); + + slen = 0; + envnum = 0; + + // header: + // UL 'total bytes' + // UL 'argnum' + // UL 'envnum' + slen += sizeof(unsigned long) * 3; + for (i = 0; i < sargc; i++) { slen += sizeof(unsigned long); slen += strlen(sargv[i]) + 1; } + +#ifdef HAVE_ENVIRON + // count how much space is needed for environment + for (i = 0; environ[i]; i++) + { + slen += sizeof(unsigned long); + slen += strlen(environ[i]) + 1; + envnum++; + } +#endif + + // how much space is needed for cwd + slen += sizeof(unsigned long); slen += strlen(cwd) + 1; + + // allocate buffer on stack sbuf = alloca(slen); + + // fill in header ((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long); ((unsigned long *)(sbuf))[1] = sargc; - pos = (unsigned char *)(&((((unsigned long *)(sbuf))[2 + sargc]))); + ((unsigned long *)(sbuf))[2] = envnum; + // pos pointer after header + pos = (unsigned char *)(&((((unsigned long *)(sbuf))[3 + sargc + envnum + 1]))); + n = 3; + + // fill in args for (i = 0; i < sargc; i++) { - ((unsigned long *)(sbuf))[2 + i] = - (unsigned long)pos - ((unsigned long)sbuf + sizeof(unsigned long)); + ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf; strcpy((char *)pos, sargv[i]); pos += strlen(sargv[i]) + 1; + n++; } + +#ifdef HAVE_ENVIRON + // fill in environ + for (i = 0; environ[i]; i++) + { + ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf; + strcpy((char *)pos, environ[i]); + pos += strlen(environ[i]) + 1; + n++; + } +#endif + + // fill in cwd + ((unsigned long *)(sbuf))[n] = (unsigned long)pos - (unsigned long)sbuf; + n++; strcpy((char *)pos, cwd); + if (write(sock, sbuf, slen) < 0) printf("elementary_quicklaunch: cannot write to socket '%s'\n", buf); close(sock);