13e12c5d1SDavid du Colombier #include "common.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier /* make a stream to a child process */ 43e12c5d1SDavid du Colombier extern stream * 53e12c5d1SDavid du Colombier instream(void) 63e12c5d1SDavid du Colombier { 73e12c5d1SDavid du Colombier stream *rv; 83e12c5d1SDavid du Colombier int pfd[2]; 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier if ((rv = (stream *)malloc(sizeof(stream))) == 0) 113e12c5d1SDavid du Colombier return 0; 123e12c5d1SDavid du Colombier if (pipe(pfd) < 0) 133e12c5d1SDavid du Colombier return 0; 143e12c5d1SDavid du Colombier if(Binit(&rv->bb, pfd[1], OWRITE) < 0){ 153e12c5d1SDavid du Colombier close(pfd[0]); 163e12c5d1SDavid du Colombier close(pfd[1]); 173e12c5d1SDavid du Colombier return 0; 183e12c5d1SDavid du Colombier } 193e12c5d1SDavid du Colombier rv->fp = &rv->bb; 203e12c5d1SDavid du Colombier rv->fd = pfd[0]; 213e12c5d1SDavid du Colombier return rv; 223e12c5d1SDavid du Colombier } 233e12c5d1SDavid du Colombier 243e12c5d1SDavid du Colombier /* make a stream from a child process */ 253e12c5d1SDavid du Colombier extern stream * 263e12c5d1SDavid du Colombier outstream(void) 273e12c5d1SDavid du Colombier { 283e12c5d1SDavid du Colombier stream *rv; 293e12c5d1SDavid du Colombier int pfd[2]; 303e12c5d1SDavid du Colombier 313e12c5d1SDavid du Colombier if ((rv = (stream *)malloc(sizeof(stream))) == 0) 323e12c5d1SDavid du Colombier return 0; 333e12c5d1SDavid du Colombier if (pipe(pfd) < 0) 343e12c5d1SDavid du Colombier return 0; 353e12c5d1SDavid du Colombier if (Binit(&rv->bb, pfd[0], OREAD) < 0){ 363e12c5d1SDavid du Colombier close(pfd[0]); 373e12c5d1SDavid du Colombier close(pfd[1]); 383e12c5d1SDavid du Colombier return 0; 393e12c5d1SDavid du Colombier } 403e12c5d1SDavid du Colombier rv->fp = &rv->bb; 413e12c5d1SDavid du Colombier rv->fd = pfd[1]; 423e12c5d1SDavid du Colombier return rv; 433e12c5d1SDavid du Colombier } 443e12c5d1SDavid du Colombier 453e12c5d1SDavid du Colombier extern void 463e12c5d1SDavid du Colombier stream_free(stream *sp) 473e12c5d1SDavid du Colombier { 483e12c5d1SDavid du Colombier int fd; 493e12c5d1SDavid du Colombier 503e12c5d1SDavid du Colombier close(sp->fd); 513e12c5d1SDavid du Colombier fd = Bfildes(sp->fp); 52*219b2ee8SDavid du Colombier Bterm(sp->fp); 533e12c5d1SDavid du Colombier close(fd); 543e12c5d1SDavid du Colombier free((char *)sp); 553e12c5d1SDavid du Colombier } 563e12c5d1SDavid du Colombier 573e12c5d1SDavid du Colombier /* start a new process */ 583e12c5d1SDavid du Colombier extern process * 59bd389b36SDavid du Colombier proc_start(char *cmd, stream *inp, stream *outp, stream *errp, int newpg, int none) 603e12c5d1SDavid du Colombier { 613e12c5d1SDavid du Colombier process *pp; 623e12c5d1SDavid du Colombier int i; 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier if ((pp = (process *)malloc(sizeof(process))) == 0) { 653e12c5d1SDavid du Colombier if (inp != 0) 663e12c5d1SDavid du Colombier stream_free(inp); 673e12c5d1SDavid du Colombier if (outp != 0) 683e12c5d1SDavid du Colombier stream_free(outp); 693e12c5d1SDavid du Colombier if (errp != 0) 703e12c5d1SDavid du Colombier stream_free(errp); 713e12c5d1SDavid du Colombier return 0; 723e12c5d1SDavid du Colombier } 733e12c5d1SDavid du Colombier pp->std[0] = inp; 743e12c5d1SDavid du Colombier pp->std[1] = outp; 753e12c5d1SDavid du Colombier pp->std[2] = errp; 763e12c5d1SDavid du Colombier switch (pp->pid = fork()) { 773e12c5d1SDavid du Colombier case -1: 783e12c5d1SDavid du Colombier proc_free(pp); 793e12c5d1SDavid du Colombier return 0; 803e12c5d1SDavid du Colombier case 0: 813e12c5d1SDavid du Colombier if(newpg) 823e12c5d1SDavid du Colombier newprocgroup(); 83bd389b36SDavid du Colombier if(none) 84bd389b36SDavid du Colombier becomenone(); 853e12c5d1SDavid du Colombier for (i=0; i<3; i++) 863e12c5d1SDavid du Colombier if (pp->std[i] != 0) 873e12c5d1SDavid du Colombier close(Bfildes(pp->std[i]->fp)); 883e12c5d1SDavid du Colombier for (i=0; i<3; i++) 893e12c5d1SDavid du Colombier if (pp->std[i] != 0) 903e12c5d1SDavid du Colombier dup(pp->std[i]->fd, i); 913e12c5d1SDavid du Colombier 923e12c5d1SDavid du Colombier for (i = 3; i < nofile; i++) 933e12c5d1SDavid du Colombier close(i); 943e12c5d1SDavid du Colombier execl("/bin/rc", "rc", "-c", cmd, 0); 953e12c5d1SDavid du Colombier perror("proc_start"); 963e12c5d1SDavid du Colombier exits("proc_start"); 973e12c5d1SDavid du Colombier default: 983e12c5d1SDavid du Colombier for (i=0; i<nsysfile; i++) 993e12c5d1SDavid du Colombier if (pp->std[i] != 0) { 1003e12c5d1SDavid du Colombier close(pp->std[i]->fd); 1013e12c5d1SDavid du Colombier pp->std[i]->fd = -1; 1023e12c5d1SDavid du Colombier } 1033e12c5d1SDavid du Colombier return pp; 1043e12c5d1SDavid du Colombier } 1053e12c5d1SDavid du Colombier } 1063e12c5d1SDavid du Colombier 1073e12c5d1SDavid du Colombier /* wait for a process to stop */ 1083e12c5d1SDavid du Colombier extern int 1093e12c5d1SDavid du Colombier proc_wait(process *pp) 1103e12c5d1SDavid du Colombier { 1113e12c5d1SDavid du Colombier Waitmsg status; 1123e12c5d1SDavid du Colombier int pid; 113*219b2ee8SDavid du Colombier char err[ERRLEN]; 1143e12c5d1SDavid du Colombier 115*219b2ee8SDavid du Colombier for(;;){ 116*219b2ee8SDavid du Colombier pid = wait(&status); 117*219b2ee8SDavid du Colombier if(pid < 0){ 118*219b2ee8SDavid du Colombier errstr(err); 119*219b2ee8SDavid du Colombier if(strstr(err, "interrupt") == 0) 120*219b2ee8SDavid du Colombier break; 121*219b2ee8SDavid du Colombier } 1223e12c5d1SDavid du Colombier if (pid==pp->pid) 1233e12c5d1SDavid du Colombier break; 1243e12c5d1SDavid du Colombier } 1253e12c5d1SDavid du Colombier pp->pid = -1; 1263e12c5d1SDavid du Colombier pp->status = status.msg[0]; 1273e12c5d1SDavid du Colombier return pp->status; 1283e12c5d1SDavid du Colombier } 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier static int junk; 1313e12c5d1SDavid du Colombier 1323e12c5d1SDavid du Colombier /* free a process */ 1333e12c5d1SDavid du Colombier extern int 1343e12c5d1SDavid du Colombier proc_free(process *pp) 1353e12c5d1SDavid du Colombier { 1363e12c5d1SDavid du Colombier int i; 1373e12c5d1SDavid du Colombier 1383e12c5d1SDavid du Colombier if(pp->std[1] == pp->std[2]) 1393e12c5d1SDavid du Colombier pp->std[2] = 0; /* avoid freeing it twice */ 1403e12c5d1SDavid du Colombier for (i = 0; i < 3; i++) 1413e12c5d1SDavid du Colombier if (pp->std[i]) 1423e12c5d1SDavid du Colombier stream_free(pp->std[i]); 1433e12c5d1SDavid du Colombier if (pp->pid >= 0){ 1443e12c5d1SDavid du Colombier USE(proc_wait(pp)); 1453e12c5d1SDavid du Colombier } 1463e12c5d1SDavid du Colombier free((char *)pp); 1473e12c5d1SDavid du Colombier return 0; 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier /* kill a process */ 1513e12c5d1SDavid du Colombier extern int 1523e12c5d1SDavid du Colombier proc_kill(process *pp) 1533e12c5d1SDavid du Colombier { 1543e12c5d1SDavid du Colombier return syskill(pp->pid); 1553e12c5d1SDavid du Colombier } 156