garbeam@2: /* garbeam@2: * (C)opyright MMVI Anselm R. Garbe garbeam@2: * See LICENSE file for license details. garbeam@2: */ garbeam@2: garbeam@2: #include garbeam@2: #include garbeam@2: #include garbeam@3: #include garbeam@5: #include garbeam@5: #include garbeam@5: #include garbeam@5: garbeam@5: #include "util.h" garbeam@2: garbeam@6: static char *shell = NULL; garbeam@6: garbeam@2: void garbeam@2: error(char *errstr, ...) { garbeam@2: va_list ap; garbeam@2: va_start(ap, errstr); garbeam@2: vfprintf(stderr, errstr, ap); garbeam@2: va_end(ap); garbeam@2: exit(1); garbeam@2: } garbeam@2: garbeam@3: static void garbeam@3: bad_malloc(unsigned int size) garbeam@3: { garbeam@3: fprintf(stderr, "fatal: could not malloc() %d bytes\n", garbeam@3: (int) size); garbeam@3: exit(1); garbeam@3: } garbeam@3: garbeam@3: void * garbeam@3: emallocz(unsigned int size) garbeam@3: { garbeam@3: void *res = calloc(1, size); garbeam@3: if(!res) garbeam@3: bad_malloc(size); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: void * garbeam@3: emalloc(unsigned int size) garbeam@3: { garbeam@3: void *res = malloc(size); garbeam@3: if(!res) garbeam@3: bad_malloc(size); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: void * garbeam@3: erealloc(void *ptr, unsigned int size) garbeam@3: { garbeam@3: void *res = realloc(ptr, size); garbeam@3: if(!res) garbeam@3: bad_malloc(size); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: char * garbeam@3: estrdup(const char *str) garbeam@3: { garbeam@3: void *res = strdup(str); garbeam@3: if(!res) garbeam@3: bad_malloc(strlen(str)); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: void garbeam@3: failed_assert(char *a, char *file, int line) garbeam@3: { garbeam@3: fprintf(stderr, "Assertion \"%s\" failed at %s:%d\n", a, file, line); garbeam@3: abort(); garbeam@3: } garbeam@3: garbeam@3: void garbeam@3: swap(void **p1, void **p2) garbeam@3: { garbeam@3: void *tmp = *p1; garbeam@3: *p1 = *p2; garbeam@3: *p2 = tmp; garbeam@3: } garbeam@5: garbeam@5: void garbeam@6: spawn(Display *dpy, const char *cmd) garbeam@5: { garbeam@6: if(!shell && !(shell = getenv("SHELL"))) garbeam@6: shell = "/bin/sh"; garbeam@6: garbeam@6: if(!cmd) garbeam@5: return; garbeam@5: if(fork() == 0) { garbeam@5: if(fork() == 0) { garbeam@5: if(dpy) garbeam@5: close(ConnectionNumber(dpy)); garbeam@9: setsid(); garbeam@9: fprintf(stderr, "gridwm: execlp %s %s -c %s", shell, shell, cmd); garbeam@9: execlp(shell, shell, "-c", cmd, NULL); garbeam@9: fprintf(stderr, "gridwm: execlp %s", cmd); garbeam@5: perror(" failed"); garbeam@5: } garbeam@5: exit (0); garbeam@5: } garbeam@5: wait(0); garbeam@5: } garbeam@6: garbeam@6: void garbeam@6: pipe_spawn(char *buf, unsigned int len, Display *dpy, const char *cmd) garbeam@6: { garbeam@6: unsigned int l, n; garbeam@6: int pfd[2]; garbeam@6: garbeam@6: if(!shell && !(shell = getenv("SHELL"))) garbeam@6: shell = "/bin/sh"; garbeam@6: garbeam@6: if(!cmd) garbeam@6: return; garbeam@6: garbeam@6: if(pipe(pfd) == -1) { garbeam@6: perror("pipe"); garbeam@6: exit(1); garbeam@6: } garbeam@6: garbeam@6: if(fork() == 0) { garbeam@6: if(dpy) garbeam@6: close(ConnectionNumber(dpy)); garbeam@9: setsid(); garbeam@6: dup2(pfd[1], STDOUT_FILENO); garbeam@6: close(pfd[0]); garbeam@6: close(pfd[1]); garbeam@9: execlp(shell, shell, "-c", cmd, NULL); garbeam@9: fprintf(stderr, "gridwm: execlp %s", cmd); garbeam@6: perror(" failed"); garbeam@6: } garbeam@6: else { garbeam@6: n = 0; garbeam@6: close(pfd[1]); garbeam@6: while(l > n) { garbeam@6: if((l = read(pfd[0], buf + n, len - n)) < 1) garbeam@6: break; garbeam@6: n += l; garbeam@6: } garbeam@6: close(pfd[0]); garbeam@6: buf[n - 1] = 0; garbeam@6: } garbeam@6: wait(0); garbeam@6: }