+/*
+ * vim:ts=8:expandtab
+ *
+ * i3 - an improved dynamic tiling window manager
+ *
+ * (c) 2009 Michael Stapelberg and contributors
+ *
+ * See file LICENSE for license information.
+ *
+ */
#include <stdio.h>
#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) {
- /* 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);
}
/*
*
*/
void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *err_message) {
- xcb_generic_error_t *error = xcb_request_check(connection, cookie);
- if (error != NULL) {
- fprintf(stderr, "ERROR: %s : %d\n", err_message , error->error_code);
- xcb_disconnect(connection);
- exit(-1);
- }
+ xcb_generic_error_t *error = xcb_request_check(connection, cookie);
+ if (error != NULL) {
+ fprintf(stderr, "ERROR: %s : %d\n", err_message , error->error_code);
+ xcb_disconnect(connection);
+ exit(-1);
+ }
}