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 become(av, 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 av[0] = SHELL; 118 av[1] = "-c"; 119 av[2] = cmd; 120 av[3] = 0; 121 return noshell_proc_start(av, inp, outp, errp, newpg, who); 122 } 123 124 /* wait for a process to stop */ 125 extern int 126 proc_wait(process *pp) 127 { 128 Waitmsg *status; 129 char err[Errlen]; 130 131 for(;;){ 132 status = wait(); 133 if(status == nil){ 134 errstr(err, sizeof(err)); 135 if(strstr(err, "interrupt") == 0) 136 break; 137 } 138 if (status->pid==pp->pid) 139 break; 140 } 141 pp->pid = -1; 142 if(status == nil) 143 pp->status = -1; 144 else 145 pp->status = status->msg[0]; 146 free(status); 147 return pp->status; 148 } 149 150 /* free a process */ 151 extern int 152 proc_free(process *pp) 153 { 154 int i; 155 156 if(pp->std[1] == pp->std[2]) 157 pp->std[2] = 0; /* avoid freeing it twice */ 158 for (i = 0; i < 3; i++) 159 if (pp->std[i]) 160 stream_free(pp->std[i]); 161 if (pp->pid >= 0) 162 proc_wait(pp); 163 free((char *)pp); 164 return 0; 165 } 166 167 /* kill a process */ 168 extern int 169 proc_kill(process *pp) 170 { 171 return syskill(pp->pid); 172 } 173