From 52dba6418ee96fb3ac2b47a7edd19821323b382f Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 20 Apr 2010 03:32:22 +0200 Subject: [PATCH] fix posible issue with statusbar when reloading wmfs spawn() now return the child pid --- src/init.c | 20 +++++-------------- src/structs.h | 1 + src/util.c | 53 +++++++++++++++++++++++++++++++++++++-------------- src/wmfs.c | 5 ++++- src/wmfs.h | 4 +++- 5 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/init.c b/src/init.c index 50bd4f1..6a9b853 100644 --- a/src/init.c +++ b/src/init.c @@ -180,45 +180,35 @@ init_root(void) void init_status(void) { - int fd; struct stat st; char *home; + conf.status_pid = -1; + estatus = False; + if(!conf.status_path) { if(!(home = getenv("HOME"))) { warnx("HOME not set, can't launch status.sh"); - estatus = False; return; } conf.status_path = emalloc(strlen(home) + strlen(DEF_STATUS) + 2, sizeof(char)); - sprintf(conf.status_path, "%s/"DEF_STATUS, home); } - if(!(fd = open(conf.status_path, O_RDONLY)) - || !fopen(conf.status_path, "r")) + if (stat(conf.status_path, &st) == -1) { - free(conf.status_path); - estatus = False; - + warn("%s", conf.status_path); return; } - stat(conf.status_path, &st); - if(st.st_size && st.st_mode & S_IXUSR) - { estatus = True; - spawn(conf.status_path); - } else warnx("status file specified in configuratin (status_path) or present in wmfs directory can't be executed, try 'chmod +x %s'.", conf.status_path); - close(fd); - return; } diff --git a/src/structs.h b/src/structs.h index b7e6122..38df242 100644 --- a/src/structs.h +++ b/src/structs.h @@ -348,6 +348,7 @@ typedef struct uint pad; int status_timing; char *status_path; + pid_t status_pid; char *autostart_path; char *autostart_command; struct diff --git a/src/util.c b/src/util.c index d50d934..8e5973a 100644 --- a/src/util.c +++ b/src/util.c @@ -200,44 +200,69 @@ get_mouse_pos(void) /** Execute a sh command * \param cmd Command + * \return child pid */ -void +int spawn(const char *format, ...) { char *sh = NULL; char cmd[512]; va_list ap; - - if(strlen(format) > 511) - { - warnx("spawn(): Error, command too long."); - return; - } + pid_t pid, ret; + int p[2], len; va_start(ap, format); - vsprintf(cmd, format, ap); + len = vsnprintf(cmd, sizeof(cmd), format, ap); va_end(ap); - if(!strlen(cmd)) - return; + if (len >= sizeof(cmd)) + { + warnx("command too long (> 512 bytes)"); + return -1; + } if(!(sh = getenv("SHELL"))) sh = "/bin/sh"; - if(fork() == 0) + if (pipe(p) == -1) { - if(fork() == 0) + warn("pipe"); + return -1; + } + + if((pid = fork()) == 0) + { + close(p[0]); + if((pid = fork()) == 0) { if(dpy) close(ConnectionNumber(dpy)); setsid(); execl(sh, sh, "-c", cmd, (char*)NULL); - exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); } + write(p[1], &pid, sizeof(pid_t)); + close(p[1]); exit(EXIT_SUCCESS); } + else if (pid != -1) + { + close(p[1]); + if (sizeof(pid_t) != read(p[0], &ret, sizeof(pid_t))) + { + warn("read"); + ret = -1; + } + close(p[0]); + waitpid(pid, NULL, 0); + } + else + { + warn("fork"); + ret = -1; + } - return; + return ret; } /** Swap two pointer. diff --git a/src/wmfs.c b/src/wmfs.c index b868673..d2f82ba 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -148,7 +148,7 @@ thread_process(void *arg) pthread_detach(pthread_self()); do { - spawn(conf.status_path); + conf.status_pid = spawn(conf.status_path); sleep(conf.status_timing); } while (!exiting && conf.status_timing != 0); } @@ -271,6 +271,9 @@ uicb_reload(uicb_t cmd) { quit(); + if (conf.status_pid != (pid_t)-1) + kill(conf.status_pid, SIGQUIT); + for(; argv_global[0] && argv_global[0] == ' '; ++argv_global); execlp(argv_global, argv_global, NULL); diff --git a/src/wmfs.h b/src/wmfs.h index 1ea6577..6726d02 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -33,6 +33,8 @@ #ifndef WMFS_H #define WMFS_H +#define _BSD_SOURCE /* vsnprintf */ +#define _POSIX_SOURCE /* kill */ /* Lib headers */ #include #include @@ -278,7 +280,7 @@ char* alias_to_str(char *conf_choice); /* }}} */ XRectangle get_mouse_pos(void); char *char_to_str(const char c); -void spawn(const char *str, ...); +int spawn(const char *str, ...); void swap_ptr(void **x, void **y); void uicb_spawn(uicb_t); char *clean_value(char *str);