URI:
       tprocess.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tprocess.c (3066B)
       ---
            1 #include "common.h"
            2 
            3 /* make a stream to a child process */
            4 extern stream *
            5 instream(void)
            6 {
            7         stream *rv;
            8         int pfd[2];
            9 
           10         if ((rv = (stream *)malloc(sizeof(stream))) == 0)
           11                 return 0;
           12         memset(rv, 0, sizeof(stream));
           13         if (pipe(pfd) < 0)
           14                 return 0;
           15         if(Binit(&rv->bb, pfd[1], OWRITE) < 0){
           16                 close(pfd[0]);
           17                 close(pfd[1]);
           18                 return 0;
           19         }
           20         rv->fp = &rv->bb;
           21         rv->fd = pfd[0];
           22         return rv;
           23 }
           24 
           25 /* make a stream from a child process */
           26 extern stream *
           27 outstream(void)
           28 {
           29         stream *rv;
           30         int pfd[2];
           31 
           32         if ((rv = (stream *)malloc(sizeof(stream))) == 0)
           33                 return 0;
           34         memset(rv, 0, sizeof(stream));
           35         if (pipe(pfd) < 0)
           36                 return 0;
           37         if (Binit(&rv->bb, pfd[0], OREAD) < 0){
           38                 close(pfd[0]);
           39                 close(pfd[1]);
           40                 return 0;
           41         }
           42         rv->fp = &rv->bb;
           43         rv->fd = pfd[1];
           44         return rv;
           45 }
           46 
           47 extern void
           48 stream_free(stream *sp)
           49 {
           50         int fd;
           51 
           52         close(sp->fd);
           53         fd = Bfildes(sp->fp);
           54         Bterm(sp->fp);
           55         close(fd);
           56         free((char *)sp);
           57 }
           58 
           59 /* start a new process */
           60 extern process *
           61 noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg, char *who)
           62 {
           63         process *pp;
           64         int i, n;
           65 
           66         if ((pp = (process *)malloc(sizeof(process))) == 0) {
           67                 if (inp != 0)
           68                         stream_free(inp);
           69                 if (outp != 0)
           70                         stream_free(outp);
           71                 if (errp != 0)
           72                         stream_free(errp);
           73                 return 0;
           74         }
           75         pp->std[0] = inp;
           76         pp->std[1] = outp;
           77         pp->std[2] = errp;
           78         switch (pp->pid = fork()) {
           79         case -1:
           80                 proc_free(pp);
           81                 return 0;
           82         case 0:
           83                 if(newpg)
           84                         sysdetach();
           85                 for (i=0; i<3; i++)
           86                         if (pp->std[i] != 0){
           87                                 close(Bfildes(pp->std[i]->fp));
           88                                 while(pp->std[i]->fd < 3)
           89                                         pp->std[i]->fd = dup(pp->std[i]->fd, -1);
           90                         }
           91                 for (i=0; i<3; i++)
           92                         if (pp->std[i] != 0)
           93                                 dup(pp->std[i]->fd, i);
           94                 for (n = sysfiles(); i < n; i++)
           95                         close(i);
           96                 if(who)
           97                         fprint(2, "warning: cannot run %s as %s\n", av[0], who);
           98                 exec(av[0], av);
           99                 perror("proc_start");
          100                 exits("proc_start");
          101         default:
          102                 for (i=0; i<3; i++)
          103                         if (pp->std[i] != 0) {
          104                                 close(pp->std[i]->fd);
          105                                 pp->std[i]->fd = -1;
          106                         }
          107                 return pp;
          108         }
          109 }
          110 
          111 /* start a new process under a shell */
          112 extern process *
          113 proc_start(char *cmd, stream *inp, stream *outp, stream *errp, int newpg, char *who)
          114 {
          115         char *av[4];
          116 
          117         upasconfig();
          118         av[0] = SHELL;
          119         av[1] = "-c";
          120         av[2] = cmd;
          121         av[3] = 0;
          122         return noshell_proc_start(av, inp, outp, errp, newpg, who);
          123 }
          124 
          125 /* wait for a process to stop */
          126 extern int
          127 proc_wait(process *pp)
          128 {
          129         Waitmsg *status;
          130         char err[Errlen];
          131 
          132         for(;;){
          133                 status = wait();
          134                 if(status == nil){
          135                         errstr(err, sizeof(err));
          136                         if(strstr(err, "interrupt") == 0)
          137                                 break;
          138                 }
          139                 if (status->pid==pp->pid)
          140                         break;
          141         }
          142         pp->pid = -1;
          143         if(status == nil)
          144                 pp->status = -1;
          145         else
          146                 pp->status = status->msg[0];
          147         pp->waitmsg = status;
          148         return pp->status;
          149 }
          150 
          151 /* free a process */
          152 extern int
          153 proc_free(process *pp)
          154 {
          155         int i;
          156 
          157         if(pp->std[1] == pp->std[2])
          158                 pp->std[2] = 0;                /* avoid freeing it twice */
          159         for (i = 0; i < 3; i++)
          160                 if (pp->std[i])
          161                         stream_free(pp->std[i]);
          162         if (pp->pid >= 0)
          163                 proc_wait(pp);
          164         free(pp->waitmsg);
          165         free((char *)pp);
          166         return 0;
          167 }
          168 
          169 /* kill a process */
          170 extern int
          171 proc_kill(process *pp)
          172 {
          173         return syskill(pp->pid);
          174 }