xref: /plan9-contrib/sys/src/cmd/upas/common/process.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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