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