Environment filtering is not needed. Instead, open applications through SHELL, double-fork
This commit is contained in:
parent
651bcc375f
commit
4589c26558
2
TODO
2
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!
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
29
src/mainx.c
29
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);
|
||||
|
||||
|
|
33
src/util.c
33
src/util.c
|
@ -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 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue