From d5fda16d6018215bfdc0e7d07f16d546030783bb Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Fri, 22 May 2015 11:08:40 +0200 Subject: [PATCH] Implement forking mode This closes #24 --- include/types.h | 3 +++ man/xedgewarp.man | 5 ++++- src/xedgewarp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/include/types.h b/include/types.h index 91e3842..3051908 100644 --- a/include/types.h +++ b/include/types.h @@ -57,4 +57,7 @@ typedef struct Config { /* How much spam should we generate? */ log_level_t log_level; + + /* If true, fork on startup */ + bool fork_mode; } Config; diff --git a/man/xedgewarp.man b/man/xedgewarp.man index 2ecb082..892d26d 100644 --- a/man/xedgewarp.man +++ b/man/xedgewarp.man @@ -8,10 +8,13 @@ xedgewarp - window manager agnostic pointer warping between outputs == SYNOPSIS -xedgewarp [-m closest|relative] [-l error|debug|trace] [-h] [-v] +xedgewarp [-b] [-m closest|relative] [-l error|debug|trace] [-h] [-v] == OPTIONS +-b:: +Run in background mode, i.e. fork on startup. + -m closest|relative:: Specifies how the mouse pointer should be warped. With "closest", the pointer is warped only as little as necessary to the closest edge on the output. With diff --git a/src/xedgewarp.c b/src/xedgewarp.c index fecfafd..b78ae4e 100644 --- a/src/xedgewarp.c +++ b/src/xedgewarp.c @@ -1,19 +1,41 @@ // vim:ts=4:sw=4:expandtab #include "all.h" #include +#include +#include +#include #ifndef __VERSION #define __VERSION "unknown" #endif +typedef void (*callback)(void); + +/* Forward declarations */ +static void run(); +static void safe_fork(callback child_callback); + xcb_connection_t *connection; xcb_window_t root; -Config config; +Config config = { + .fake_outputs = NULL, + .warp_mode = WM_CLOSEST, + .log_level = L_ERROR, + .fork_mode = false +}; int main(int argc, char *argv[]) { atexit(on_xedgewarp_exit); parse_arguments(argc, argv); + if (config.fork_mode) { + safe_fork(run); + } else { + run(); + } +} + +static void run() { initialize_x11(); initialize_xedgewarp(); @@ -68,7 +90,7 @@ void on_xedgewarp_exit(void) { */ void parse_arguments(int argc, char *argv[]) { int c; - while ((c = getopt(argc, argv, "m:l:o:vh")) != -1) { + while ((c = getopt(argc, argv, "m:l:o:bvh")) != -1) { switch (c) { case 'm': if (strcasecmp(optarg, "closest") == 0) @@ -92,16 +114,20 @@ void parse_arguments(int argc, char *argv[]) { case 'o': config.fake_outputs = strdup(optarg); break; + case 'b': + config.fork_mode = true; + break; case 'v': fprintf(stderr, "%s version %s\n", argv[0], __VERSION); exit(EXIT_SUCCESS); break; case 'h': default: - fprintf(stderr, "Usage: %s [-m closest|relative] [-l error|debug|trace] [-v] [-h]", argv[0]); + fprintf(stderr, "Usage: %s [-b] [-m closest|relative] [-l error|debug|trace] [-v] [-h]", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, "\t-h display the usage and exit\n"); fprintf(stderr, "\t-v display the version and exit\n"); + fprintf(stderr, "\t-b run in background mode, i.e. fork on startup\n"); fprintf(stderr, "\t-m closest|relative\n" "\t\tSpecifies how the mouse pointer should be warped.\n"); fprintf(stderr, "\t-l error|debug|trace\n" @@ -112,3 +138,21 @@ void parse_arguments(int argc, char *argv[]) { } } } + +/* Double fork to prevent zombie processes */ +static void safe_fork(callback child_callback) { + pid_t pid = fork(); + if (!pid) { + if (!fork()) { + /* this is the child that keeps going */ + (*child_callback)(); + } else { + /* the first child process exits */ + exit(EXIT_SUCCESS); + } + } else { + /* this is the original process */ + /* wait for the first child to exit which it will immediately */ + waitpid(pid, NULL, 0); + } +}