arg@644: /* (C)opyright MMVI-MMVII Anselm R. Garbe garbeam@2: * See LICENSE file for license details. garbeam@2: */ garbeam@76: #include "dwm.h" garbeam@2: #include garbeam@2: #include garbeam@2: #include garbeam@5: #include garbeam@5: #include garbeam@5: garbeam@84: /* extern */ garbeam@76: garbeam@3: void * arg@461: emallocz(unsigned int size) { garbeam@3: void *res = calloc(1, size); arg@123: garbeam@3: if(!res) arg@325: eprint("fatal: could not malloc() %u bytes\n", size); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: void arg@461: eprint(const char *errstr, ...) { garbeam@76: va_list ap; arg@123: garbeam@76: va_start(ap, errstr); garbeam@76: vfprintf(stderr, errstr, ap); garbeam@76: va_end(ap); garbeam@92: exit(EXIT_FAILURE); garbeam@76: } garbeam@76: garbeam@76: void arg@461: spawn(Arg *arg) { arg@189: static char *shell = NULL; arg@123: arg@189: if(!shell && !(shell = getenv("SHELL"))) arg@189: shell = "/bin/sh"; arg@189: if(!arg->cmd) garbeam@5: return; arg@471: /* The double-fork construct avoids zombie processes and keeps the code arg@471: * clean from stupid signal handlers. */ garbeam@5: if(fork() == 0) { garbeam@5: if(fork() == 0) { garbeam@5: if(dpy) garbeam@5: close(ConnectionNumber(dpy)); garbeam@9: setsid(); arg@338: execl(shell, shell, "-c", arg->cmd, (char *)NULL); arg@217: fprintf(stderr, "dwm: execl '%s -c %s'", shell, arg->cmd); garbeam@5: perror(" failed"); garbeam@5: } arg@138: exit(0); garbeam@5: } garbeam@5: wait(0); garbeam@5: }