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

This commit is contained in:
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:
* 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!

View File

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

View File

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

View File

@ -287,7 +287,7 @@ void parse_command(xcb_connection_t *conn, const char *command) {
/* Is it an <exec>? */
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;
}

View File

@ -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);

View File

@ -2,25 +2,38 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.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) {
pid_t pid;
if ((pid = vfork()) == 0) {
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 */
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);
execl(shell, shell, "-c", command, NULL);
/* not reached */
}
exit(0);
}
wait(0);
}
/*