Deleted Added
full compact
popen.c (40188) popen.c (74769)
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35#if 0
35static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/6/93";
36static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/6/93";
37#endif
38static const char rcsid[] =
39 "$FreeBSD: head/usr.bin/mail/popen.c 74769 2001-03-25 04:57:05Z mikeh $";
36#endif /* not lint */
37
38#include "rcv.h"
39#include <sys/wait.h>
40#include <fcntl.h>
41#include "extern.h"
42
43#define READ 0

--- 6 unchanged lines hidden (view full) ---

50 struct fp *link;
51};
52static struct fp *fp_head;
53
54struct child {
55 int pid;
56 char done;
57 char free;
40#endif /* not lint */
41
42#include "rcv.h"
43#include <sys/wait.h>
44#include <fcntl.h>
45#include "extern.h"
46
47#define READ 0

--- 6 unchanged lines hidden (view full) ---

54 struct fp *link;
55};
56static struct fp *fp_head;
57
58struct child {
59 int pid;
60 char done;
61 char free;
58 union wait status;
62 int status;
59 struct child *link;
60};
61static struct child *child;
62static struct child *findchild __P((int));
63static void delchild __P((struct child *));
63 struct child *link;
64};
65static struct child *child;
66static struct child *findchild __P((int));
67static void delchild __P((struct child *));
68static int file_pid __P((FILE *));
64
65FILE *
66Fopen(file, mode)
67 char *file, *mode;
68{
69 FILE *fp;
70
71 if ((fp = fopen(file, mode)) != NULL) {

--- 89 unchanged lines hidden (view full) ---

161void
162register_file(fp, pipe, pid)
163 FILE *fp;
164 int pipe, pid;
165{
166 struct fp *fpp;
167
168 if ((fpp = (struct fp *) malloc(sizeof *fpp)) == NULL)
69
70FILE *
71Fopen(file, mode)
72 char *file, *mode;
73{
74 FILE *fp;
75
76 if ((fp = fopen(file, mode)) != NULL) {

--- 89 unchanged lines hidden (view full) ---

166void
167register_file(fp, pipe, pid)
168 FILE *fp;
169 int pipe, pid;
170{
171 struct fp *fpp;
172
173 if ((fpp = (struct fp *) malloc(sizeof *fpp)) == NULL)
169 panic("Out of memory");
174 err(1, "Out of memory");
170 fpp->fp = fp;
171 fpp->pipe = pipe;
172 fpp->pid = pid;
173 fpp->link = fp_head;
174 fp_head = fpp;
175}
176
177void
178unregister_file(fp)
179 FILE *fp;
180{
181 struct fp **pp, *p;
182
183 for (pp = &fp_head; p = *pp; pp = &p->link)
184 if (p->fp == fp) {
185 *pp = p->link;
186 free((char *) p);
187 return;
188 }
175 fpp->fp = fp;
176 fpp->pipe = pipe;
177 fpp->pid = pid;
178 fpp->link = fp_head;
179 fp_head = fpp;
180}
181
182void
183unregister_file(fp)
184 FILE *fp;
185{
186 struct fp **pp, *p;
187
188 for (pp = &fp_head; p = *pp; pp = &p->link)
189 if (p->fp == fp) {
190 *pp = p->link;
191 free((char *) p);
192 return;
193 }
189 panic("Invalid file pointer");
194 errx(1, "Invalid file pointer");
195 /*NOTREACHED*/
190}
191
196}
197
198int
192file_pid(fp)
193 FILE *fp;
194{
195 struct fp *p;
196
197 for (p = fp_head; p; p = p->link)
198 if (p->fp == fp)
199 return (p->pid);
199file_pid(fp)
200 FILE *fp;
201{
202 struct fp *p;
203
204 for (p = fp_head; p; p = p->link)
205 if (p->fp == fp)
206 return (p->pid);
200 panic("Invalid file pointer");
207 errx(1, "Invalid file pointer");
201 /*NOTREACHED*/
202}
203
204/*
205 * Run a command without a shell, with optional arguments and splicing
206 * of stdin and stdout. The command name can be a sequence of words.
207 * Signals must be handled by the caller.
208 * "Mask" contains the signals to ignore in the new process.

--- 18 unchanged lines hidden (view full) ---

227start_command(cmd, mask, infd, outfd, a0, a1, a2)
228 char *cmd;
229 int mask, infd, outfd;
230 char *a0, *a1, *a2;
231{
232 int pid;
233
234 if ((pid = fork()) < 0) {
208 /*NOTREACHED*/
209}
210
211/*
212 * Run a command without a shell, with optional arguments and splicing
213 * of stdin and stdout. The command name can be a sequence of words.
214 * Signals must be handled by the caller.
215 * "Mask" contains the signals to ignore in the new process.

--- 18 unchanged lines hidden (view full) ---

234start_command(cmd, mask, infd, outfd, a0, a1, a2)
235 char *cmd;
236 int mask, infd, outfd;
237 char *a0, *a1, *a2;
238{
239 int pid;
240
241 if ((pid = fork()) < 0) {
235 perror("fork");
242 warn("fork");
236 return -1;
237 }
238 if (pid == 0) {
239 char *argv[100];
240 int i = getrawlist(cmd, argv, sizeof argv / sizeof *argv);
241
242 if ((argv[i++] = a0) != NOSTR &&
243 (argv[i++] = a1) != NOSTR &&
244 (argv[i++] = a2) != NOSTR)
245 argv[i] = NOSTR;
246 prepare_child(mask, infd, outfd);
247 execvp(argv[0], argv);
243 return -1;
244 }
245 if (pid == 0) {
246 char *argv[100];
247 int i = getrawlist(cmd, argv, sizeof argv / sizeof *argv);
248
249 if ((argv[i++] = a0) != NOSTR &&
250 (argv[i++] = a1) != NOSTR &&
251 (argv[i++] = a2) != NOSTR)
252 argv[i] = NOSTR;
253 prepare_child(mask, infd, outfd);
254 execvp(argv[0], argv);
248 perror(argv[0]);
255 warn("%s", argv[0]);
249 _exit(1);
250 }
251 return pid;
252}
253
254void
255prepare_child(mask, infd, outfd)
256 int mask, infd, outfd;

--- 34 unchanged lines hidden (view full) ---

291{
292 register struct child **cpp;
293
294 for (cpp = &child; *cpp != NULL && (*cpp)->pid != pid;
295 cpp = &(*cpp)->link)
296 ;
297 if (*cpp == NULL) {
298 *cpp = (struct child *) malloc(sizeof (struct child));
256 _exit(1);
257 }
258 return pid;
259}
260
261void
262prepare_child(mask, infd, outfd)
263 int mask, infd, outfd;

--- 34 unchanged lines hidden (view full) ---

298{
299 register struct child **cpp;
300
301 for (cpp = &child; *cpp != NULL && (*cpp)->pid != pid;
302 cpp = &(*cpp)->link)
303 ;
304 if (*cpp == NULL) {
305 *cpp = (struct child *) malloc(sizeof (struct child));
306 if (*cpp == NULL)
307 err(1, "Out of memory");
299 (*cpp)->pid = pid;
300 (*cpp)->done = (*cpp)->free = 0;
301 (*cpp)->link = NULL;
302 }
303 return *cpp;
304}
305
306static void

--- 8 unchanged lines hidden (view full) ---

315 free((char *) cp);
316}
317
318void
319sigchild(signo)
320 int signo;
321{
322 int pid;
308 (*cpp)->pid = pid;
309 (*cpp)->done = (*cpp)->free = 0;
310 (*cpp)->link = NULL;
311 }
312 return *cpp;
313}
314
315static void

--- 8 unchanged lines hidden (view full) ---

324 free((char *) cp);
325}
326
327void
328sigchild(signo)
329 int signo;
330{
331 int pid;
323 union wait status;
332 int status;
324 register struct child *cp;
325
333 register struct child *cp;
334
326 while ((pid =
327 wait3((int *)&status, WNOHANG, (struct rusage *)0)) > 0) {
335 while ((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0) {
328 cp = findchild(pid);
329 if (cp->free)
330 delchild(cp);
331 else {
332 cp->done = 1;
333 cp->status = status;
334 }
335 }
336}
337
336 cp = findchild(pid);
337 if (cp->free)
338 delchild(cp);
339 else {
340 cp->done = 1;
341 cp->status = status;
342 }
343 }
344}
345
338union wait wait_status;
346int wait_status;
339
340/*
341 * Wait for a specific child to die.
342 */
343int
344wait_child(pid)
345 int pid;
346{
347 int mask = sigblock(sigmask(SIGCHLD));
348 register struct child *cp = findchild(pid);
349
350 while (!cp->done)
351 sigpause(mask);
352 wait_status = cp->status;
353 delchild(cp);
354 sigsetmask(mask);
347
348/*
349 * Wait for a specific child to die.
350 */
351int
352wait_child(pid)
353 int pid;
354{
355 int mask = sigblock(sigmask(SIGCHLD));
356 register struct child *cp = findchild(pid);
357
358 while (!cp->done)
359 sigpause(mask);
360 wait_status = cp->status;
361 delchild(cp);
362 sigsetmask(mask);
355 return wait_status.w_status ? -1 : 0;
363 return((WIFEXITED(wait_status) && WEXITSTATUS(wait_status)) ? -1 : 0);
356}
357
358/*
359 * Mark a child as don't care.
360 */
361void
362free_child(pid)
363 int pid;
364{
365 int mask = sigblock(sigmask(SIGCHLD));
366 register struct child *cp = findchild(pid);
367
368 if (cp->done)
369 delchild(cp);
370 else
371 cp->free = 1;
372 sigsetmask(mask);
373}
364}
365
366/*
367 * Mark a child as don't care.
368 */
369void
370free_child(pid)
371 int pid;
372{
373 int mask = sigblock(sigmask(SIGCHLD));
374 register struct child *cp = findchild(pid);
375
376 if (cp->done)
377 delchild(cp);
378 else
379 cp->free = 1;
380 sigsetmask(mask);
381}