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 if (pipe(pfd) < 0) 13 return 0; 14 if(Binit(&rv->bb, pfd[1], OWRITE) < 0){ 15 close(pfd[0]); 16 close(pfd[1]); 17 return 0; 18 } 19 rv->fp = &rv->bb; 20 rv->fd = pfd[0]; 21 return rv; 22 } 23 24 /* make a stream from a child process */ 25 extern stream * 26 outstream(void) 27 { 28 stream *rv; 29 int pfd[2]; 30 31 if ((rv = (stream *)malloc(sizeof(stream))) == 0) 32 return 0; 33 if (pipe(pfd) < 0) 34 return 0; 35 if (Binit(&rv->bb, pfd[0], OREAD) < 0){ 36 close(pfd[0]); 37 close(pfd[1]); 38 return 0; 39 } 40 rv->fp = &rv->bb; 41 rv->fd = pfd[1]; 42 return rv; 43 } 44 45 extern void 46 stream_free(stream *sp) 47 { 48 int fd; 49 50 close(sp->fd); 51 fd = Bfildes(sp->fp); 52 Bterm(sp->fp); 53 close(fd); 54 free((char *)sp); 55 } 56 57 /* start a new process */ 58 extern process * 59 proc_start(char *cmd, stream *inp, stream *outp, stream *errp, int newpg, int none) 60 { 61 process *pp; 62 int i; 63 64 if ((pp = (process *)malloc(sizeof(process))) == 0) { 65 if (inp != 0) 66 stream_free(inp); 67 if (outp != 0) 68 stream_free(outp); 69 if (errp != 0) 70 stream_free(errp); 71 return 0; 72 } 73 pp->std[0] = inp; 74 pp->std[1] = outp; 75 pp->std[2] = errp; 76 switch (pp->pid = fork()) { 77 case -1: 78 proc_free(pp); 79 return 0; 80 case 0: 81 if(newpg) 82 newprocgroup(); 83 if(none) 84 becomenone(); 85 for (i=0; i<3; i++) 86 if (pp->std[i] != 0) 87 close(Bfildes(pp->std[i]->fp)); 88 for (i=0; i<3; i++) 89 if (pp->std[i] != 0) 90 dup(pp->std[i]->fd, i); 91 92 for (i = 3; i < nofile; i++) 93 close(i); 94 execl("/bin/rc", "rc", "-c", cmd, 0); 95 perror("proc_start"); 96 exits("proc_start"); 97 default: 98 for (i=0; i<nsysfile; i++) 99 if (pp->std[i] != 0) { 100 close(pp->std[i]->fd); 101 pp->std[i]->fd = -1; 102 } 103 return pp; 104 } 105 } 106 107 /* wait for a process to stop */ 108 extern int 109 proc_wait(process *pp) 110 { 111 Waitmsg status; 112 int pid; 113 char err[ERRLEN]; 114 115 for(;;){ 116 pid = wait(&status); 117 if(pid < 0){ 118 errstr(err); 119 if(strstr(err, "interrupt") == 0) 120 break; 121 } 122 if (pid==pp->pid) 123 break; 124 } 125 pp->pid = -1; 126 pp->status = status.msg[0]; 127 return pp->status; 128 } 129 130 static int junk; 131 132 /* free a process */ 133 extern int 134 proc_free(process *pp) 135 { 136 int i; 137 138 if(pp->std[1] == pp->std[2]) 139 pp->std[2] = 0; /* avoid freeing it twice */ 140 for (i = 0; i < 3; i++) 141 if (pp->std[i]) 142 stream_free(pp->std[i]); 143 if (pp->pid >= 0){ 144 USE(proc_wait(pp)); 145 } 146 free((char *)pp); 147 return 0; 148 } 149 150 /* kill a process */ 151 extern int 152 proc_kill(process *pp) 153 { 154 return syskill(pp->pid); 155 } 156