fix auicklaunch to transport environment as well as args. fixes

startup id tracking for e.



SVN revision: 74380
This commit is contained in:
Carsten Haitzler 2012-07-25 09:56:00 +00:00
parent 3c241774c0
commit cbad53a5c8
4 changed files with 132 additions and 22 deletions

View File

@ -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.

View File

@ -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 <unistd.h>
], [
extern char **environ;
], [
AC_DEFINE(HAVE_ENVIRON, 1, [extern environ exists])
])
AC_TRY_COMPILE([
#include <stdlib.h>
], [
clearenv();
], [
AC_DEFINE(HAVE_CLEARENV, 1, [extern environ exists])
])
AC_OUTPUT([
Makefile

View File

@ -9,12 +9,19 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef HAVE_ENVIRON
# define _GNU_SOURCE 1
#endif
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#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)

View File

@ -7,6 +7,9 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef HAVE_ENVIRON
# define _GNU_SOURCE 1
#endif
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -14,12 +17,16 @@
# include <alloca.h>
#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);