From 3459ed0b201aed14e0dcbb1b80a99e6209d16da7 Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Mon, 29 Nov 2010 21:17:04 +0100 Subject: [PATCH 01/12] Define optarg and optind (was breaking compilation on NetBSD) --- src/wmfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wmfs.c b/src/wmfs.c index 0cbc3cb..0a6c8b6 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -420,6 +420,8 @@ main(int argc, char **argv) { int i; char *ol = "csgVS"; + extern char *optarg; + extern int optind; argv_global = xstrdup(argv[0]); sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME")); From c90a5743b3c066768ad3198d48256c4a98a786cd Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Mon, 29 Nov 2010 22:08:01 +0100 Subject: [PATCH 02/12] Parser: Use read() instead of mmap() --- src/parse.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/parse.c b/src/parse.c index dcca36c..be1641f 100644 --- a/src/parse.c +++ b/src/parse.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -183,19 +182,22 @@ parse_keywords(const char *filename) return NULL; } + buf = zmalloc(st.st_size+1); + + if (read(fd, buf, st.st_size) == -1) { + warn("%s", filename); + free(buf); + close(fd); + return NULL; + } + + buf[st.st_size] = '\0'; + file = zcalloc(sizeof(*file)); bufname = zcalloc(sizeof(*bufname) * BUFSIZ); file->name = strdup(path); file->parent = NULL; - buf = (char *)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, SEEK_SET); - - if (buf == (char*)MAP_FAILED) { - warn("%s", filename); - return NULL; - } - - for(i = 0, j = 0, line = 1; i < (size_t)st.st_size; i++) { if (!head && tail) @@ -303,7 +305,7 @@ parse_keywords(const char *filename) bufname[j++] = buf[i]; } - munmap(buf, st.st_size); + free(buf); free(bufname); warnx("%s read", file->name); From 77e458048d43ff52c694cac633f46714e6aaa45c Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Fri, 3 Dec 2010 11:06:33 +0100 Subject: [PATCH 03/12] Fix tag_new() tag name possible overflow + random memory access --- src/tag.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tag.c b/src/tag.c index be6ca1c..26df2a5 100644 --- a/src/tag.c +++ b/src/tag.c @@ -508,18 +508,20 @@ tag_new(int s, char *name) ++conf.ntag[s]; + /* TODO: memleak here */ if(!name || strlen(name) == 0) { if(conf.tagnamecount) { - displayedName = zmalloc(2); - sprintf(displayedName, "[%d]", conf.ntag[s]); + /* displayedName = zmalloc(2); */ + xasprintf(&displayedName, "[%d]", conf.ntag[s]); } else displayedName = conf.default_tag.name; } else - displayedName = name; + displayedName = xstrdup(name); + Tag t = { displayedName, NULL, 0, 0, conf.default_tag.mwfact, conf.default_tag.nmaster, From d0058146dd6c7d9ede05206f9121849fea5d84ef Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Fri, 3 Dec 2010 12:36:51 +0100 Subject: [PATCH 04/12] Remove non used function get_mouse_pos --- src/util.c | 14 -------------- src/wmfs.h | 1 - 2 files changed, 15 deletions(-) diff --git a/src/util.c b/src/util.c index f6527cf..f3147c1 100644 --- a/src/util.c +++ b/src/util.c @@ -248,20 +248,6 @@ alias_to_str(char *conf_choice) } /* }}} */ -/** Get the mouse pointer position. -*/ -XRectangle -get_mouse_pos(void) -{ - Window dum; - int d, u; - XRectangle ret; - - XQueryPointer(dpy, ROOT, &dum, &dum, (int*)&ret.x, (int*)&ret.y, &d, &d, (uint *)&u); - - return ret; -} - /** Execute a sh command * \param cmd Command * \return child pid diff --git a/src/wmfs.h b/src/wmfs.h index 76106c7..48f325c 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -308,7 +308,6 @@ uint char_to_button(char *name, name_to_uint_t blist[]); Layout layout_name_to_struct(Layout lt[], char *name, int n, const func_name_list_t llist[]); char* alias_to_str(char *conf_choice); /* }}} */ -XRectangle get_mouse_pos(void); char *char_to_str(const char c); int spawn(const char *str, ...); void swap_ptr(void **x, void **y); From c8a74878a13559864c40cf03bab4aa4d7f7d3226 Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Fri, 3 Dec 2010 16:59:07 +0100 Subject: [PATCH 05/12] Remove double fork for spawn and kill status with SIGTERM --- src/event.c | 2 -- src/init.c | 12 ++++++++++++ src/util.c | 52 +++++++++++----------------------------------------- src/wmfs.c | 2 +- src/wmfs.h | 2 +- 5 files changed, 25 insertions(+), 45 deletions(-) diff --git a/src/event.c b/src/event.c index e1e0989..c391521 100644 --- a/src/event.c +++ b/src/event.c @@ -695,7 +695,5 @@ getevent(XEvent ev) break; } - wait((int[]){0}); - return; } diff --git a/src/init.c b/src/init.c index 21b01e0..2e8e168 100644 --- a/src/init.c +++ b/src/init.c @@ -55,12 +55,24 @@ const func_name_list_t layout_list[] = { NULL, NULL } }; +static void sigchld(int); + +static void +sigchld(int sig) +{ + (void)sig; + if (signal(SIGCHLD, sigchld) == SIG_ERR) + warn("signal(SIGCHLD)"); + while (waitpid(-1, NULL, WNOHANG) > 0); +} + /** Init WMFS */ void init(void) { /* First init */ + sigchld(0); ewmh_init_hints(); init_conf(); init_gc(); diff --git a/src/util.c b/src/util.c index f3147c1..7cd4edc 100644 --- a/src/util.c +++ b/src/util.c @@ -30,6 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include "wmfs.h" /** malloc with error support and size_t overflow protection @@ -252,15 +253,14 @@ alias_to_str(char *conf_choice) * \param cmd Command * \return child pid */ -int +pid_t spawn(const char *format, ...) { char *sh = NULL; char cmd[512]; va_list ap; - pid_t pid, ret; - int p[2]; size_t len; + pid_t pid; va_start(ap, format); len = vsnprintf(cmd, sizeof(cmd), format, ap); @@ -275,48 +275,18 @@ spawn(const char *format, ...) if(!(sh = getenv("SHELL"))) sh = "/bin/sh"; - if (pipe(p) == -1) - { - 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_FAILURE); - } - - if (sizeof(pid_t) != write(p[1], &pid, sizeof(pid_t))) - warn("write"); - - 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; + if(dpy) + close(ConnectionNumber(dpy)); + setsid(); + execl(sh, sh, "-c", cmd, (char*)NULL); + err(1, "execl(%s)", cmd); } + if (pid == -1) + warn("fork()"); - return ret; + return pid; } /** Swap two pointer. diff --git a/src/wmfs.c b/src/wmfs.c index 0a6c8b6..bb65499 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -134,7 +134,7 @@ quit(void) /* kill status script */ if (conf.status_pid != (pid_t)-1) - kill(conf.status_pid, SIGQUIT); + kill(conf.status_pid, SIGTERM); return; } diff --git a/src/wmfs.h b/src/wmfs.h index 48f325c..ebe5e35 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -309,7 +309,7 @@ Layout layout_name_to_struct(Layout lt[], char *name, int n, const func_name_lis char* alias_to_str(char *conf_choice); /* }}} */ char *char_to_str(const char c); -int spawn(const char *str, ...); +pid_t spawn(const char *str, ...); void swap_ptr(void **x, void **y); void uicb_spawn(uicb_t); char *clean_value(char *str); From 9e457b3832633961a15a05dd1f5b5f1687088ebc Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 7 Dec 2010 00:42:37 +0100 Subject: [PATCH 06/12] Remove glibc stuffs, wmfs is not ansi C that's a fact --- Makefile.in | 2 +- src/util.c | 2 +- src/wmfs.h | 11 ----------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 020ae06..eafb89a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -32,7 +32,7 @@ src/wmfs.c # flags CFLAGS+= -DXDG_CONFIG_DIR=\"${XDG_CONFIG_DIR}\" CFLAGS+= -DWMFS_VERSION=\"${VERSION}\" -CFLAGS+= -W -Wall -Wextra -ansi +CFLAGS+= -W -Wall -Wextra OBJS= ${SRCS:.c=.o} diff --git a/src/util.c b/src/util.c index 7cd4edc..961b92a 100644 --- a/src/util.c +++ b/src/util.c @@ -30,7 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#define _GNU_SOURCE #include "wmfs.h" /** malloc with error support and size_t overflow protection diff --git a/src/wmfs.h b/src/wmfs.h index ebe5e35..e548c49 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -33,17 +33,6 @@ #ifndef WMFS_H #define WMFS_H -/* glibc stuff */ -#ifndef _BSD_SOURCE -#define _BSD_SOURCE /* vsnprintf */ -#endif -#ifndef _POSIX_SOURCE -#define _POSIX_SOURCE /* kill */ -#endif -#ifndef _GNU_SOURCE -#define _GNU_SOURCE /* asprintf */ -#endif - /* Lib headers */ #include #include From 6882cfb986660e9f04d4989720873d256e5f97bf Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 7 Dec 2010 00:12:54 +0100 Subject: [PATCH 07/12] Only one handler for signals --- src/init.c | 12 ------------ src/wmfs.c | 29 ++++++++++++++++++++++------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/init.c b/src/init.c index 2e8e168..21b01e0 100644 --- a/src/init.c +++ b/src/init.c @@ -55,24 +55,12 @@ const func_name_list_t layout_list[] = { NULL, NULL } }; -static void sigchld(int); - -static void -sigchld(int sig) -{ - (void)sig; - if (signal(SIGCHLD, sigchld) == SIG_ERR) - warn("signal(SIGCHLD)"); - while (waitpid(-1, NULL, WNOHANG) > 0); -} - /** Init WMFS */ void init(void) { /* First init */ - sigchld(0); ewmh_init_hints(); init_conf(); init_gc(); diff --git a/src/wmfs.c b/src/wmfs.c index bb65499..305fa4f 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -32,6 +32,8 @@ #include "wmfs.h" +static void signal_handle(int); + int errorhandler(Display *d, XErrorEvent *event) { @@ -399,13 +401,24 @@ update_status(void) /** Signal handle function */ -void +static void signal_handle(int sig) { - (void)sig; - exiting = True; - quit(); - exit(EXIT_SUCCESS); + switch (sig) + { + case SIGQUIT: + case SIGTERM: + exiting = True; + quit(); + exit(EXIT_SUCCESS); + break; + case SIGCHLD: + /* re-set signal handler and wait childs */ + if (signal(SIGCHLD, &signal_handle) == SIG_ERR) + warn("signal(%d)", SIGCHLD); + while (waitpid(-1, NULL, WNOHANG) > 0); + break; + } return; } @@ -422,6 +435,7 @@ main(int argc, char **argv) char *ol = "csgVS"; extern char *optarg; extern int optind; + int sigs[] = { SIGTERM, SIGQUIT, SIGCHLD }; argv_global = xstrdup(argv[0]); sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME")); @@ -503,8 +517,9 @@ main(int argc, char **argv) errx(EXIT_FAILURE, "cannot open X server."); /* Set signal handler */ - (void)signal(SIGTERM, &signal_handle); - (void)signal(SIGINT, &signal_handle); + for (i = sigs[0]; i < (int)LEN(sigs); i++) + if (signal(sigs[i], &signal_handle) == SIG_ERR) + warn("signal(%d)", sigs[i]); /* Check if an other WM is already running; set the error handler */ XSetErrorHandler(errorhandler); From 87575a019d3e19267c10433c6f55a87f832dcbdf Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 7 Dec 2010 00:28:12 +0100 Subject: [PATCH 08/12] Use SIGALRM instead of pthread for status script --- configure | 2 -- src/wmfs.c | 50 +++++++++++++++----------------------------------- 2 files changed, 15 insertions(+), 37 deletions(-) diff --git a/configure b/configure index 27b83e0..7a89d41 100755 --- a/configure +++ b/configure @@ -79,8 +79,6 @@ fi [ -n "$USE_XRANDR" ] && CFLAGS="$CFLAGS -DHAVE_XRANDR" [ -n "$USE_IMLIB2" ] && CFLAGS="$CFLAGS -DHAVE_IMLIB" -LDFLAGS="$LDFLAGS -lpthread" - cat > Makefile << EOF PREFIX=$PREFIX XDG_CONFIG_DIR=$XDG_CONFIG_DIR diff --git a/src/wmfs.c b/src/wmfs.c index 305fa4f..2f327f3 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -141,49 +141,19 @@ quit(void) return; } -void * -thread_process(void *arg) -{ - XEvent ev; - - /* X event loop */ - if(arg) - { - while(!exiting && !XNextEvent(dpy, &ev)) - getevent(ev); - } - /* Status checking loop with timing */ - else - { - pthread_detach(pthread_self()); - do - { - conf.status_pid = spawn(conf.status_path); - sleep(conf.status_timing); - } while (!exiting && conf.status_timing != 0); - } - pthread_exit(NULL); -} - /** WMFS main loop. */ void mainloop(void) { XEvent ev; - pthread_t evloop, evstatus; - void *ret; - if(!estatus) - while(!exiting && !XNextEvent(dpy, &ev)) - getevent(ev); - else - { - pthread_create(&evloop, NULL, thread_process, "1"); - pthread_create(&evstatus, NULL, thread_process, NULL); + /* launch status loop */ + if (estatus) + signal_handle(SIGALRM); - (void)pthread_join(evloop, &ret); - } + while(!exiting && !XNextEvent(dpy, &ev)) + getevent(ev); return; } @@ -418,6 +388,16 @@ signal_handle(int sig) warn("signal(%d)", SIGCHLD); while (waitpid(-1, NULL, WNOHANG) > 0); break; + case SIGALRM: + /* re-set signal handler */ + if (signal(SIGALRM, &signal_handle) == SIG_ERR) + warn("signal(%d)", SIGALRM); + /* exec status script */ + conf.status_pid = spawn(conf.status_path); + /* re-set timer */ + if (conf.status_timing > 0) + alarm(conf.status_timing); + break; } return; From d606f999f9d4d80a453813eb8143223be1e7293e Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 7 Dec 2010 00:30:36 +0100 Subject: [PATCH 09/12] Add distclean target (clean && remove Makefile) --- Makefile.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index eafb89a..f29a06e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -50,6 +50,10 @@ ${MAN}.gz: ${MAN} clean: rm -f ${OBJS} wmfs ${MAN}.gz +distclean: clean + rm -f Makefile + + install: all @echo installing executable file to ${DESTDIR}${PREFIX}/bin mkdir -p ${DESTDIR}${PREFIX}/bin @@ -77,5 +81,5 @@ uninstall: -.PHONY: all clean install uninstall +.PHONY: all clean distclean install uninstall From 6c332c9ea57c5d9da02fd33c2ed53b0c8aac7e45 Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 7 Dec 2010 01:19:28 +0100 Subject: [PATCH 10/12] Oops. Fix signal not handled at all --- src/wmfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wmfs.c b/src/wmfs.c index 2f327f3..b02a899 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -497,7 +497,7 @@ main(int argc, char **argv) errx(EXIT_FAILURE, "cannot open X server."); /* Set signal handler */ - for (i = sigs[0]; i < (int)LEN(sigs); i++) + for (i = 0; i < (int)LEN(sigs); i++) if (signal(sigs[i], &signal_handle) == SIG_ERR) warn("signal(%d)", sigs[i]); From ce3813608c316a8aba57bbac74c8b8997b1fa4ad Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 7 Dec 2010 01:34:22 +0100 Subject: [PATCH 11/12] Status script not spawned if still running --- src/wmfs.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/wmfs.c b/src/wmfs.c index b02a899..a62717f 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -135,7 +135,7 @@ quit(void) XCloseDisplay(dpy); /* kill status script */ - if (conf.status_pid != (pid_t)-1) + if (conf.status_pid != -1) kill(conf.status_pid, SIGTERM); return; @@ -374,6 +374,8 @@ update_status(void) static void signal_handle(int sig) { + pid_t pid; + switch (sig) { case SIGQUIT: @@ -386,14 +388,17 @@ signal_handle(int sig) /* re-set signal handler and wait childs */ if (signal(SIGCHLD, &signal_handle) == SIG_ERR) warn("signal(%d)", SIGCHLD); - while (waitpid(-1, NULL, WNOHANG) > 0); + while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) + if (pid == conf.status_pid) + conf.status_pid = -1; break; case SIGALRM: /* re-set signal handler */ if (signal(SIGALRM, &signal_handle) == SIG_ERR) warn("signal(%d)", SIGALRM); - /* exec status script */ - conf.status_pid = spawn(conf.status_path); + /* exec status script (only if still not running) */ + if (conf.status_pid == (pid_t)-1) + conf.status_pid = spawn(conf.status_path); /* re-set timer */ if (conf.status_timing > 0) alarm(conf.status_timing); From 6072c2d811f26a1636cb01ac03de886b57541706 Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 7 Dec 2010 01:38:21 +0100 Subject: [PATCH 12/12] Set default tag params. (patch by bacardi55) fixes #51 --- src/config.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/config.c b/src/config.c index ca9c84b..1755392 100644 --- a/src/config.c +++ b/src/config.c @@ -546,14 +546,14 @@ conf_tag_section(void) ((j == -1) ? ++k : --l)) { ++conf.ntag[k]; - tags[k][conf.ntag[k]].name = fetch_opt_first(tag[i], "", "name").str; - tags[k][conf.ntag[k]].mwfact = fetch_opt_first(tag[i], "0.65", "mwfact").fnum; - tags[k][conf.ntag[k]].nmaster = fetch_opt_first(tag[i], "1", "nmaster").num; - tags[k][conf.ntag[k]].resizehint = fetch_opt_first(tag[i], "false", "resizehint").bool; + tags[k][conf.ntag[k]].name = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "", "name").str, "name").str; + tags[k][conf.ntag[k]].mwfact = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "0.65", "mwfact").str, "mwfact").fnum; + tags[k][conf.ntag[k]].nmaster = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "1", "nmaster").str, "nmaster").num; + tags[k][conf.ntag[k]].resizehint = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "false", "resizehint").str, "resizehint").bool; tags[k][conf.ntag[k]].abovefc = fetch_opt_first(tag[i], "false", "abovefc").bool; tags[k][conf.ntag[k]].layers = 1; - tmp = fetch_opt_first(tag[i], "top", "infobar_position").str; + tmp = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "top", "infobar_position").str, "infobar_position").str; if(!strcmp(tmp ,"none") || !strcmp(tmp, "hide") || !strcmp(tmp, "hidden")) tags[k][conf.ntag[k]].barpos = IB_Hide; @@ -563,7 +563,7 @@ conf_tag_section(void) tags[k][conf.ntag[k]].barpos = IB_Top; tags[k][conf.ntag[k]].layout = layout_name_to_struct(conf.layout, - fetch_opt_first(tag[i], "tile_right", "layout").str, + fetch_opt_first(tag[i], fetch_opt_first(def_tag, "title_right", "layout").str, "layout").str, conf.nlayout, layout_list);