int threadspawnl(int fd[3], char *cmd, ...) { char **argv, *s; int n, pid; va_list arg; va_start(arg, cmd); for(n=0; va_arg(arg, char*) != nil; n++) ; n++; va_end(arg); argv = malloc(n*sizeof(argv[0])); if(argv == nil) return -1; va_start(arg, cmd); for(n=0; (s=va_arg(arg, char*)) != nil; n++) argv[n] = s; argv[n] = 0; va_end(arg); pid = threadspawn(fd, cmd, argv); free(argv); return pid; }
Waitmsg* runprocfd(char *file, char **v, int fd[3]) { int pid, i; threadwaitchan(); pid = threadspawn(fd, file, v); for(i=0; i<3; i++) close(fd[i]); if(pid < 0) return nil; return procwait(pid); }
void kickjob(Job *j) { int i; int fd[3]; int p[2]; VtLog *l; if((fd[0] = open("/dev/null", ORDWR)) < 0) { vtlogprint(errlog, "%T open /dev/null: %r\n"); return; } if(pipe(p) < 0) { vtlogprint(errlog, "%T pipe: %r\n"); close(fd[0]); return; } qlock(&j->lk); l = j->oldlog; j->oldlog = j->newlog; j->newlog = l; qlock(&l->lk); for(i=0; i<l->nchunk; i++) l->chunk[i].wp = l->chunk[i].p; qunlock(&l->lk); j->oldok = j->newok; j->newok = -1; qunlock(&j->lk); fd[1] = p[1]; fd[2] = p[1]; j->pid = threadspawn(fd, j->argv[0], j->argv); if(j->pid < 0) { vtlogprint(errlog, "%T exec %s: %r\n", j->argv[0]); close(fd[0]); close(fd[1]); close(p[0]); } // fd[0], fd[1], fd[2] are closed now j->pipe = p[0]; j->nrun++; vtproc(piper, j); }
void getxselarg(Text* t) { char* av[] = { "xsel2arg", 0 }; int pfd[2], sfd[3], pid, n, nb, nr, nulls; char buf[1024]; Rune *r; textdelete(t, 0, t->file->b.nc, TRUE); if(pipe(pfd) < 0) { warning(nil, "getxselarg: can't create pipe"); return; } fcntl(pfd[0], F_SETFD, FD_CLOEXEC); fcntl(pfd[1], F_SETFD, FD_CLOEXEC); sfd[0] = open("/dev/null", OREAD); sfd[1] = pfd[0]; sfd[2] = dup(erroutfd, -1); pid = threadspawn(sfd, av[0], av); if(pid == -1) { warning(nil, "can't spawn thread %s: %r\n", av[0]); return; } while(0 < (n = read(pfd[1], buf, 1024))) { r = runemalloc(n+1); cvttorunes(buf, n, r, &nb, &nr, &nulls); textinsert(t, 0, r, nr, TRUE); free(r); } textsetselect(t, 0, t->file->b.nc); }
void putxsel(Text* t) { char* av[] = { "setguisel", 0, 0 }; int pfd[2], sfd[3], pid, n, m, q, q0, q1; Rune *r; char *s; q0 = t->q0; q1 = t->q1; if(q0 == q1) return; if(pipe(pfd) < 0) { warning(nil, "putxsel: can't create pipe"); return; } fcntl(pfd[0], F_SETFD, FD_CLOEXEC); fcntl(pfd[1], F_SETFD, FD_CLOEXEC); sfd[0] = pfd[0]; sfd[1] = open("/dev/null", OWRITE); sfd[2] = dup(erroutfd, -1); if(t->file->name) av[1] = runetobyte(t->file->name, t->file->nname); pid = threadspawn(sfd, av[0], av); free(av[1]); if(pid == -1) { warning(nil, "can't spawn thread %s: %r\n", av[0]); return; } r = fbufalloc(); s = fbufalloc(); for(q=q0; q<q1; q+=n) { n = q1 - q; if(n > BUFSIZE/UTFmax) n = BUFSIZE/UTFmax; bufread(&t->file->b, q, r, n); m = snprint(s, BUFSIZE+1, "%.*S", n, r); if(write(pfd[1], s, m) != m) { warning(nil, "error writing to setguisel: %r\n"); break; } } fbuffree(r); fbuffree(s); close(pfd[1]); newsel(t); }
void threadmain(int argc, char **argv) { int p[2], fd[3], pid[2]; char *a[4], *devdraw; ARGBEGIN{}ARGEND if(argc != 1) usage(); // Make sure we don't kill our parent whilst killing // our children. setsid(); if(pipe(p) < 0) sysfatal("pipe: %r"); fd[0] = dup(p[0], -1); fd[1] = dup(p[0], -1); fd[2] = dup(2, -1); a[0] = "rc"; a[1] = "-c"; a[2] = argv[0]; a[3] = nil; if((pid[0] = threadspawn(fd, a[0], a)) < 0) sysfatal("threadspawn: %r"); fd[0] = dup(p[1], -1); fd[1] = dup(p[1], -1); fd[2] = dup(2, -1); putenv("NOLIBTHREADDAEMONIZE", "1"); devdraw = getenv("DEVDRAW"); if(devdraw == nil) devdraw = "devdraw"; if((pid[1] = threadspawnl(fd, devdraw, devdraw, "(devdraw)", nil)) < 0) sysfatal("threadspawnl: %r"); close(p[0]); close(p[1]); recvp(threadwaitchan()); postnote(PNGROUP, pid[0], "hangup"); postnote(PNGROUP, pid[1], "hangup"); //recvp(threadwaitchan()); threadexitsall(""); /* if ((pid = fork()) < 0) sysfatal("fork: %r"); switch(pid){ case 0: close(p[0]); dup(p[1], 0); dup(p[1], 1); a[0] = "rc"; a[1] = "-c"; a[2] = argv[0]; a[3] = nil; if(exec("rc", a) < 0) sysfatal("execl: %r"); default: close(p[1]); dup(p[0], 0); dup(p[0], 1); putenv("NOLIBTHREADDAEMONIZE", "1"); devdraw = getenv("DEVDRAW"); if(devdraw == nil) devdraw = "devdraw"; if(execl(devdraw, devdraw, "(devdraw)", nil) < 0) sysfatal("execl: %r"); } exits(0); */ }