123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include "common.h"
- /* make a stream to a child process */
- extern stream *
- instream(void)
- {
- stream *rv;
- int pfd[2];
- if ((rv = (stream *)malloc(sizeof(stream))) == 0)
- return 0;
- memset(rv, 0, sizeof(stream));
- if (pipe(pfd) < 0)
- return 0;
- if(Binit(&rv->bb, pfd[1], OWRITE) < 0){
- close(pfd[0]);
- close(pfd[1]);
- return 0;
- }
- rv->fp = &rv->bb;
- rv->fd = pfd[0];
- return rv;
- }
- /* make a stream from a child process */
- extern stream *
- outstream(void)
- {
- stream *rv;
- int pfd[2];
- if ((rv = (stream *)malloc(sizeof(stream))) == 0)
- return 0;
- memset(rv, 0, sizeof(stream));
- if (pipe(pfd) < 0)
- return 0;
- if (Binit(&rv->bb, pfd[0], OREAD) < 0){
- close(pfd[0]);
- close(pfd[1]);
- return 0;
- }
- rv->fp = &rv->bb;
- rv->fd = pfd[1];
- return rv;
- }
- extern void
- stream_free(stream *sp)
- {
- int fd;
- close(sp->fd);
- fd = Bfildes(sp->fp);
- Bterm(sp->fp);
- close(fd);
- free((char *)sp);
- }
- /* start a new process */
- extern process *
- noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg, char *who)
- {
- process *pp;
- int i, n;
- if ((pp = (process *)malloc(sizeof(process))) == 0) {
- if (inp != 0)
- stream_free(inp);
- if (outp != 0)
- stream_free(outp);
- if (errp != 0)
- stream_free(errp);
- return 0;
- }
- pp->std[0] = inp;
- pp->std[1] = outp;
- pp->std[2] = errp;
- switch (pp->pid = fork()) {
- case -1:
- proc_free(pp);
- return 0;
- case 0:
- if(newpg)
- sysdetach();
- for (i=0; i<3; i++)
- if (pp->std[i] != 0){
- close(Bfildes(pp->std[i]->fp));
- while(pp->std[i]->fd < 3)
- pp->std[i]->fd = dup(pp->std[i]->fd, -1);
- }
- for (i=0; i<3; i++)
- if (pp->std[i] != 0)
- dup(pp->std[i]->fd, i);
- for (n = sysfiles(); i < n; i++)
- close(i);
- if(who)
- become(av, who);
- exec(av[0], av);
- perror("proc_start");
- exits("proc_start");
- default:
- for (i=0; i<3; i++)
- if (pp->std[i] != 0) {
- close(pp->std[i]->fd);
- pp->std[i]->fd = -1;
- }
- return pp;
- }
- }
- /* start a new process under a shell */
- extern process *
- proc_start(char *cmd, stream *inp, stream *outp, stream *errp, int newpg, char *who)
- {
- char *av[4];
- av[0] = SHELL;
- av[1] = "-c";
- av[2] = cmd;
- av[3] = 0;
- return noshell_proc_start(av, inp, outp, errp, newpg, who);
- }
- /* wait for a process to stop */
- extern int
- proc_wait(process *pp)
- {
- Waitmsg *status;
- char err[Errlen];
- for(;;){
- status = wait();
- if(status == nil){
- errstr(err, sizeof(err));
- if(strstr(err, "interrupt") == 0)
- break;
- }
- if (status->pid==pp->pid)
- break;
- }
- pp->pid = -1;
- if(status == nil)
- pp->status = -1;
- else
- pp->status = status->msg[0];
- pp->waitmsg = status;
- return pp->status;
- }
- /* free a process */
- extern int
- proc_free(process *pp)
- {
- int i;
- if(pp->std[1] == pp->std[2])
- pp->std[2] = 0; /* avoid freeing it twice */
- for (i = 0; i < 3; i++)
- if (pp->std[i])
- stream_free(pp->std[i]);
- if (pp->pid >= 0)
- proc_wait(pp);
- free(pp->waitmsg);
- free((char *)pp);
- return 0;
- }
- /* kill a process */
- extern int
- proc_kill(process *pp)
- {
- return syskill(pp->pid);
- }
|