Environment filtering is not needed. Instead, open applications through SHELL, double-fork

next
Michael Stapelberg 2009-02-14 01:36:12 +01:00
parent 651bcc375f
commit 4589c26558
6 changed files with 32 additions and 41 deletions

2
TODO
View File

@ -1,7 +1,7 @@
TODO list, in order of importance: TODO list, in order of importance:
* freely resizable (e.g. using your mouse, for now) percentage of rows/cols * 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) * fullscreen (implementing a mode, like default, stacked)
* xinerama * xinerama
* document stuff! * document stuff!

View File

@ -12,7 +12,6 @@ extern Display *xkbdpy;
extern TAILQ_HEAD(bindings_head, Binding) bindings; extern TAILQ_HEAD(bindings_head, Binding) bindings;
extern xcb_event_handlers_t evenths; extern xcb_event_handlers_t evenths;
extern char *pattern; extern char *pattern;
extern char **environment;
extern int num_screens; extern int num_screens;
#endif #endif

View File

@ -1,7 +1,7 @@
#ifndef _UTIL_H #ifndef _UTIL_H
#define _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); void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *err_message);
#endif #endif

View File

@ -287,7 +287,7 @@ void parse_command(xcb_connection_t *conn, const char *command) {
/* Is it an <exec>? */ /* Is it an <exec>? */
if (strncmp(command, "exec ", strlen("exec ")) == 0) { if (strncmp(command, "exec ", strlen("exec ")) == 0) {
printf("starting \"%s\"\n", command + strlen("exec ")); printf("starting \"%s\"\n", command + strlen("exec "));
start_application(command+strlen("exec "), NULL); start_application(command+strlen("exec "));
return; return;
} }

View File

@ -42,10 +42,6 @@ static const int LEFT = 5;
static const int BOTTOM = 5; static const int BOTTOM = 5;
static const int RIGHT = 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. */ /* hm, xcb_wm wants us to implement this. */
table_t *byChild = 0; table_t *byChild = 0;
table_t *byParent = 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 main(int argc, char *argv[], char *env[]) {
int i, e = 0; int i, screens;
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();
xcb_connection_t *c; xcb_connection_t *c;
xcb_property_handlers_t prophs; xcb_property_handlers_t prophs;
xcb_window_t root; 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(&evenths, 0, sizeof(xcb_event_handlers_t));
memset(&prophs, 0, sizeof(xcb_property_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); c = xcb_connect(NULL, &screens);
printf("x screen is %d\n", screens);
/* TODO: this has to be more beautiful somewhen */ /* TODO: this has to be more beautiful somewhen */
int major, minor, error; int major, minor, error;
@ -414,7 +393,7 @@ int main(int argc, char *argv[], char *env[]) {
printf("Checking for Xinerama...\n"); printf("Checking for Xinerama...\n");
initialize_xinerama(c); initialize_xinerama(c);
start_application(TERMINAL, NULL); start_application(TERMINAL);
xcb_flush(c); xcb_flush(c);

View File

@ -2,25 +2,38 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <sys/wait.h>
#include "i3.h" #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 applications parent exits (immediately),
* the application is reparented to init (process-id 1), which correctly handles
* childs, so we dont 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) { void start_application(const char *command) {
pid_t pid; if (fork() == 0) {
if ((pid = vfork()) == 0) { /* Child process */
/* This is the child */ if (fork() == 0) {
char *argv[2]; /* Stores the path of the shell */
/* TODO: For now, we ignore args. Later on, they should be parsed static const char *shell = NULL;
correctly (like in the shell?) */
argv[0] = strdup(path); if (shell == NULL)
argv[1] = NULL; if ((shell = getenv("SHELL")) == NULL)
execve(path, argv, environment); shell = "/bin/sh";
/* not reached */
/* This is the child */
execl(shell, shell, "-c", command, NULL);
/* not reached */
}
exit(0);
} }
wait(0);
} }
/* /*