13e12c5d1SDavid du Colombier #include "common.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier /* make a stream to a child process */
43e12c5d1SDavid du Colombier extern stream *
instream(void)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;
127dd7cddfSDavid du Colombier memset(rv, 0, sizeof(stream));
133e12c5d1SDavid du Colombier if (pipe(pfd) < 0)
143e12c5d1SDavid du Colombier return 0;
153e12c5d1SDavid du Colombier if(Binit(&rv->bb, pfd[1], OWRITE) < 0){
163e12c5d1SDavid du Colombier close(pfd[0]);
173e12c5d1SDavid du Colombier close(pfd[1]);
183e12c5d1SDavid du Colombier return 0;
193e12c5d1SDavid du Colombier }
203e12c5d1SDavid du Colombier rv->fp = &rv->bb;
213e12c5d1SDavid du Colombier rv->fd = pfd[0];
223e12c5d1SDavid du Colombier return rv;
233e12c5d1SDavid du Colombier }
243e12c5d1SDavid du Colombier
253e12c5d1SDavid du Colombier /* make a stream from a child process */
263e12c5d1SDavid du Colombier extern stream *
outstream(void)273e12c5d1SDavid du Colombier outstream(void)
283e12c5d1SDavid du Colombier {
293e12c5d1SDavid du Colombier stream *rv;
303e12c5d1SDavid du Colombier int pfd[2];
313e12c5d1SDavid du Colombier
323e12c5d1SDavid du Colombier if ((rv = (stream *)malloc(sizeof(stream))) == 0)
333e12c5d1SDavid du Colombier return 0;
347dd7cddfSDavid du Colombier memset(rv, 0, sizeof(stream));
353e12c5d1SDavid du Colombier if (pipe(pfd) < 0)
363e12c5d1SDavid du Colombier return 0;
373e12c5d1SDavid du Colombier if (Binit(&rv->bb, pfd[0], OREAD) < 0){
383e12c5d1SDavid du Colombier close(pfd[0]);
393e12c5d1SDavid du Colombier close(pfd[1]);
403e12c5d1SDavid du Colombier return 0;
413e12c5d1SDavid du Colombier }
423e12c5d1SDavid du Colombier rv->fp = &rv->bb;
433e12c5d1SDavid du Colombier rv->fd = pfd[1];
443e12c5d1SDavid du Colombier return rv;
453e12c5d1SDavid du Colombier }
463e12c5d1SDavid du Colombier
473e12c5d1SDavid du Colombier extern void
stream_free(stream * sp)483e12c5d1SDavid du Colombier stream_free(stream *sp)
493e12c5d1SDavid du Colombier {
503e12c5d1SDavid du Colombier int fd;
513e12c5d1SDavid du Colombier
523e12c5d1SDavid du Colombier close(sp->fd);
533e12c5d1SDavid du Colombier fd = Bfildes(sp->fp);
54219b2ee8SDavid du Colombier Bterm(sp->fp);
553e12c5d1SDavid du Colombier close(fd);
563e12c5d1SDavid du Colombier free((char *)sp);
573e12c5d1SDavid du Colombier }
583e12c5d1SDavid du Colombier
593e12c5d1SDavid du Colombier /* start a new process */
603e12c5d1SDavid du Colombier extern process *
noshell_proc_start(char ** av,stream * inp,stream * outp,stream * errp,int newpg,char * who)617dd7cddfSDavid du Colombier noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg, char *who)
623e12c5d1SDavid du Colombier {
633e12c5d1SDavid du Colombier process *pp;
647dd7cddfSDavid du Colombier int i, n;
653e12c5d1SDavid du Colombier
663e12c5d1SDavid du Colombier if ((pp = (process *)malloc(sizeof(process))) == 0) {
673e12c5d1SDavid du Colombier if (inp != 0)
683e12c5d1SDavid du Colombier stream_free(inp);
693e12c5d1SDavid du Colombier if (outp != 0)
703e12c5d1SDavid du Colombier stream_free(outp);
713e12c5d1SDavid du Colombier if (errp != 0)
723e12c5d1SDavid du Colombier stream_free(errp);
733e12c5d1SDavid du Colombier return 0;
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier pp->std[0] = inp;
763e12c5d1SDavid du Colombier pp->std[1] = outp;
773e12c5d1SDavid du Colombier pp->std[2] = errp;
783e12c5d1SDavid du Colombier switch (pp->pid = fork()) {
793e12c5d1SDavid du Colombier case -1:
803e12c5d1SDavid du Colombier proc_free(pp);
813e12c5d1SDavid du Colombier return 0;
823e12c5d1SDavid du Colombier case 0:
833e12c5d1SDavid du Colombier if(newpg)
847dd7cddfSDavid du Colombier sysdetach();
853e12c5d1SDavid du Colombier for (i=0; i<3; i++)
867dd7cddfSDavid du Colombier if (pp->std[i] != 0){
873e12c5d1SDavid du Colombier close(Bfildes(pp->std[i]->fp));
887dd7cddfSDavid du Colombier while(pp->std[i]->fd < 3)
897dd7cddfSDavid du Colombier pp->std[i]->fd = dup(pp->std[i]->fd, -1);
907dd7cddfSDavid du Colombier }
913e12c5d1SDavid du Colombier for (i=0; i<3; i++)
923e12c5d1SDavid du Colombier if (pp->std[i] != 0)
933e12c5d1SDavid du Colombier dup(pp->std[i]->fd, i);
947dd7cddfSDavid du Colombier for (n = sysfiles(); i < n; i++)
953e12c5d1SDavid du Colombier close(i);
967dd7cddfSDavid du Colombier if(who)
977dd7cddfSDavid du Colombier become(av, who);
987dd7cddfSDavid du Colombier exec(av[0], av);
993e12c5d1SDavid du Colombier perror("proc_start");
1003e12c5d1SDavid du Colombier exits("proc_start");
1013e12c5d1SDavid du Colombier default:
1027dd7cddfSDavid du Colombier for (i=0; i<3; i++)
1033e12c5d1SDavid du Colombier if (pp->std[i] != 0) {
1043e12c5d1SDavid du Colombier close(pp->std[i]->fd);
1053e12c5d1SDavid du Colombier pp->std[i]->fd = -1;
1063e12c5d1SDavid du Colombier }
1073e12c5d1SDavid du Colombier return pp;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier }
1103e12c5d1SDavid du Colombier
1117dd7cddfSDavid du Colombier /* start a new process under a shell */
1127dd7cddfSDavid du Colombier extern process *
proc_start(char * cmd,stream * inp,stream * outp,stream * errp,int newpg,char * who)1137dd7cddfSDavid du Colombier proc_start(char *cmd, stream *inp, stream *outp, stream *errp, int newpg, char *who)
1147dd7cddfSDavid du Colombier {
1157dd7cddfSDavid du Colombier char *av[4];
1167dd7cddfSDavid du Colombier
1177dd7cddfSDavid du Colombier av[0] = SHELL;
1187dd7cddfSDavid du Colombier av[1] = "-c";
1197dd7cddfSDavid du Colombier av[2] = cmd;
1207dd7cddfSDavid du Colombier av[3] = 0;
1217dd7cddfSDavid du Colombier return noshell_proc_start(av, inp, outp, errp, newpg, who);
1227dd7cddfSDavid du Colombier }
1237dd7cddfSDavid du Colombier
1243e12c5d1SDavid du Colombier /* wait for a process to stop */
1253e12c5d1SDavid du Colombier extern int
proc_wait(process * pp)1263e12c5d1SDavid du Colombier proc_wait(process *pp)
1273e12c5d1SDavid du Colombier {
1289a747e4fSDavid du Colombier Waitmsg *status;
1299a747e4fSDavid du Colombier char err[Errlen];
1303e12c5d1SDavid du Colombier
131219b2ee8SDavid du Colombier for(;;){
1329a747e4fSDavid du Colombier status = wait();
1339a747e4fSDavid du Colombier if(status == nil){
134*3b86f2f8SDavid du Colombier rerrstr(err, sizeof(err));
135219b2ee8SDavid du Colombier if(strstr(err, "interrupt") == 0)
136219b2ee8SDavid du Colombier break;
137219b2ee8SDavid du Colombier }
1389a747e4fSDavid du Colombier if (status->pid==pp->pid)
1393e12c5d1SDavid du Colombier break;
1403e12c5d1SDavid du Colombier }
1413e12c5d1SDavid du Colombier pp->pid = -1;
1429a747e4fSDavid du Colombier if(status == nil)
1439a747e4fSDavid du Colombier pp->status = -1;
1449a747e4fSDavid du Colombier else
1459a747e4fSDavid du Colombier pp->status = status->msg[0];
1462b7fd5adSDavid du Colombier pp->waitmsg = status;
1473e12c5d1SDavid du Colombier return pp->status;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier
1503e12c5d1SDavid du Colombier /* free a process */
1513e12c5d1SDavid du Colombier extern int
proc_free(process * pp)1523e12c5d1SDavid du Colombier proc_free(process *pp)
1533e12c5d1SDavid du Colombier {
1543e12c5d1SDavid du Colombier int i;
1553e12c5d1SDavid du Colombier
1563e12c5d1SDavid du Colombier if(pp->std[1] == pp->std[2])
1573e12c5d1SDavid du Colombier pp->std[2] = 0; /* avoid freeing it twice */
1583e12c5d1SDavid du Colombier for (i = 0; i < 3; i++)
1593e12c5d1SDavid du Colombier if (pp->std[i])
1603e12c5d1SDavid du Colombier stream_free(pp->std[i]);
1619a747e4fSDavid du Colombier if (pp->pid >= 0)
1629a747e4fSDavid du Colombier proc_wait(pp);
1632b7fd5adSDavid du Colombier free(pp->waitmsg);
1643e12c5d1SDavid du Colombier free((char *)pp);
1653e12c5d1SDavid du Colombier return 0;
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier
1683e12c5d1SDavid du Colombier /* kill a process */
1693e12c5d1SDavid du Colombier extern int
proc_kill(process * pp)1703e12c5d1SDavid du Colombier proc_kill(process *pp)
1713e12c5d1SDavid du Colombier {
1723e12c5d1SDavid du Colombier return syskill(pp->pid);
1733e12c5d1SDavid du Colombier }
174