From 4589c265581021f77fbafa82ab1f5e984163ca5c Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 14 Feb 2009 01:36:12 +0100 Subject: [PATCH] Environment filtering is not needed. Instead, open applications through SHELL, double-fork --- TODO | 2 +- include/i3.h | 1 - include/util.h | 2 +- src/commands.c | 2 +- src/mainx.c | 29 ++++------------------------- src/util.c | 37 +++++++++++++++++++++++++------------ 6 files changed, 32 insertions(+), 41 deletions(-) diff --git a/TODO b/TODO index 46f1ea23..43cd8bf9 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ TODO list, in order of importance: * freely resizable (e.g. using your mouse, for now) percentage of rows/cols - * fullscreen (handling of applications) + * fullscreen (handling of applications, mplayer, firefox, xpdf, wmctrl) * fullscreen (implementing a mode, like default, stacked) * xinerama * document stuff! diff --git a/include/i3.h b/include/i3.h index d2453f47..c9fc80ed 100644 --- a/include/i3.h +++ b/include/i3.h @@ -12,7 +12,6 @@ extern Display *xkbdpy; extern TAILQ_HEAD(bindings_head, Binding) bindings; extern xcb_event_handlers_t evenths; extern char *pattern; -extern char **environment; extern int num_screens; #endif diff --git a/include/util.h b/include/util.h index 9eb2a447..05e05f2e 100644 --- a/include/util.h +++ b/include/util.h @@ -1,7 +1,7 @@ #ifndef _UTIL_H #define _UTIL_H -void start_application(const char *path, const char *args); +void start_application(const char *command); void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *err_message); #endif diff --git a/src/commands.c b/src/commands.c index 8e3161cf..23b188ab 100644 --- a/src/commands.c +++ b/src/commands.c @@ -287,7 +287,7 @@ void parse_command(xcb_connection_t *conn, const char *command) { /* Is it an ? */ if (strncmp(command, "exec ", strlen("exec ")) == 0) { printf("starting \"%s\"\n", command + strlen("exec ")); - start_application(command+strlen("exec "), NULL); + start_application(command+strlen("exec ")); return; } diff --git a/src/mainx.c b/src/mainx.c index 359e3f74..2d2188e3 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -42,10 +42,6 @@ static const int LEFT = 5; static const int BOTTOM = 5; static const int RIGHT = 5; -/* This is the filtered environment which will be passed to opened applications. - * It contains DISPLAY (naturally) and locales stuff (LC_*, LANG) */ -char **environment; - /* hm, xcb_wm wants us to implement this. */ table_t *byChild = 0; table_t *byParent = 0; @@ -273,28 +269,13 @@ static void initialize_xinerama(xcb_connection_t *conn) { } int main(int argc, char *argv[], char *env[]) { - int i, e = 0; - - for (i = 0; (env[i] != NULL); i++) - if (strncmp(env[i], "LC_", strlen("LC_")) == 0 || - strncmp(env[i], "LANG=", strlen("LANG=")) == 0 || - strncmp(env[i], "DISPLAY=", strlen("DISPLAY=")) == 0) { - printf("Passing environment \"%s\"\n", env[i]); - environment = realloc(environment, sizeof(char*) * ++e); - environment[e-1] = env[i]; - } - - /* environment has to be NULL-terminated */ - environment = realloc(environment, sizeof(char*) * ++e); - environment[e-1] = NULL; - - init_table(); - + int i, screens; xcb_connection_t *c; xcb_property_handlers_t prophs; xcb_window_t root; - int screens; + /* Initialize the table data structures for each workspace */ + init_table(); memset(&evenths, 0, sizeof(xcb_event_handlers_t)); memset(&prophs, 0, sizeof(xcb_property_handlers_t)); @@ -306,8 +287,6 @@ int main(int argc, char *argv[], char *env[]) { c = xcb_connect(NULL, &screens); - printf("x screen is %d\n", screens); - /* TODO: this has to be more beautiful somewhen */ int major, minor, error; @@ -414,7 +393,7 @@ int main(int argc, char *argv[], char *env[]) { printf("Checking for Xinerama...\n"); initialize_xinerama(c); - start_application(TERMINAL, NULL); + start_application(TERMINAL); xcb_flush(c); diff --git a/src/util.c b/src/util.c index 1263cdc4..81ae50df 100644 --- a/src/util.c +++ b/src/util.c @@ -2,25 +2,38 @@ #include #include #include +#include #include "i3.h" /* - * Starts the given application with the given args. + * Starts the given application by passing it through a shell. We use double fork + * to avoid zombie processes. As the started application’s parent exits (immediately), + * the application is reparented to init (process-id 1), which correctly handles + * childs, so we don’t have to do it :-). + * + * The shell is determined by looking for the SHELL environment variable. If it + * does not exist, /bin/sh is used. * */ -void start_application(const char *path, const char *args) { - pid_t pid; - if ((pid = vfork()) == 0) { - /* This is the child */ - char *argv[2]; - /* TODO: For now, we ignore args. Later on, they should be parsed - correctly (like in the shell?) */ - argv[0] = strdup(path); - argv[1] = NULL; - execve(path, argv, environment); - /* not reached */ +void start_application(const char *command) { + if (fork() == 0) { + /* Child process */ + if (fork() == 0) { + /* Stores the path of the shell */ + static const char *shell = NULL; + + if (shell == NULL) + if ((shell = getenv("SHELL")) == NULL) + shell = "/bin/sh"; + + /* This is the child */ + execl(shell, shell, "-c", command, NULL); + /* not reached */ + } + exit(0); } + wait(0); } /* -- 2.39.5