X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/07b0d2860d14640f898da7fd6375424b297f5d1f..a12ff48697cac43c0bd58aadc3f665316752562b:/usr/src/usr.bin/mail/popen.c diff --git a/usr/src/usr.bin/mail/popen.c b/usr/src/usr.bin/mail/popen.c index 623801ecdd..b46b8ae526 100644 --- a/usr/src/usr.bin/mail/popen.c +++ b/usr/src/usr.bin/mail/popen.c @@ -1,51 +1,69 @@ /* - * Copyright (c) 1980 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. * * %sccs.include.redist.c% */ #ifndef lint -static char sccsid[] = "@(#)popen.c 5.15 (Berkeley) %G%"; +static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) %G%"; #endif /* not lint */ #include "rcv.h" -#include #include +#include +#include "extern.h" #define READ 0 #define WRITE 1 -static int *pid; struct fp { FILE *fp; int pipe; + int pid; struct fp *link; }; static struct fp *fp_head; +struct child { + int pid; + char done; + char free; + union wait status; + struct child *link; +}; +static struct child *child; +static struct child *findchild __P((int)); +static void delchild __P((struct child *)); + FILE * Fopen(file, mode) char *file, *mode; { FILE *fp; - if ((fp = fopen(file, mode)) != NULL) - register_file(fp, 0); + if ((fp = fopen(file, mode)) != NULL) { + register_file(fp, 0, 0); + (void) fcntl(fileno(fp), F_SETFD, 1); + } return fp; } FILE * Fdopen(fd, mode) + int fd; char *mode; { FILE *fp; - if ((fp = fdopen(fd, mode)) != NULL) - register_file(fp, 0); + if ((fp = fdopen(fd, mode)) != NULL) { + register_file(fp, 0, 0); + (void) fcntl(fileno(fp), F_SETFD, 1); + } return fp; } +int Fclose(fp) FILE *fp; { @@ -60,12 +78,13 @@ Popen(cmd, mode) { int p[2]; int myside, hisside, fd0, fd1; + int pid; FILE *fp; - if (pid == 0) - pid = (int *) malloc((unsigned) sizeof (int) * getdtablesize()); if (pipe(p) < 0) return NULL; + (void) fcntl(p[READ], F_SETFD, 1); + (void) fcntl(p[WRITE], F_SETFD, 1); if (*mode == 'r') { myside = p[READ]; fd0 = -1; @@ -75,32 +94,34 @@ Popen(cmd, mode) hisside = fd0 = p[READ]; fd1 = -1; } - if ((pid[myside] = start_command(cmd, 0, fd0, fd1, NOSTR)) < 0) { + if ((pid = start_command(cmd, 0, fd0, fd1, NOSTR, NOSTR, NOSTR)) < 0) { close(p[READ]); close(p[WRITE]); return NULL; } (void) close(hisside); if ((fp = fdopen(myside, mode)) != NULL) - register_file(fp, 1); + register_file(fp, 1, pid); return fp; } +int Pclose(ptr) FILE *ptr; { int i; int omask; - i = fileno(ptr); + i = file_pid(ptr); unregister_file(ptr); (void) fclose(ptr); omask = sigblock(sigmask(SIGINT)|sigmask(SIGHUP)); - i = wait_child(pid[i]); + i = wait_child(i); sigsetmask(omask); return i; } +void close_all_files() { @@ -111,8 +132,10 @@ close_all_files() (void) Fclose(fp_head->fp); } -register_file(fp, pipe) +void +register_file(fp, pipe, pid) FILE *fp; + int pipe, pid; { struct fp *fpp; @@ -120,10 +143,12 @@ register_file(fp, pipe) panic("Out of memory"); fpp->fp = fp; fpp->pipe = pipe; + fpp->pid = pid; fpp->link = fp_head; fp_head = fpp; } +void unregister_file(fp) FILE *fp; { @@ -135,11 +160,19 @@ unregister_file(fp) free((char *) p); return; } - /* XXX - * Ignore this for now; there may still be uncaught - * duplicate closes. panic("Invalid file pointer"); - */ +} + +file_pid(fp) + FILE *fp; +{ + struct fp *p; + + for (p = fp_head; p; p = p->link) + if (p->fp == fp) + return (p->pid); + panic("Invalid file pointer"); + /*NOTREACHED*/ } /* @@ -150,6 +183,7 @@ unregister_file(fp) * SIGINT is enabled unless it's in the mask. */ /*VARARGS4*/ +int run_command(cmd, mask, infd, outfd, a0, a1, a2) char *cmd; int mask, infd, outfd; @@ -163,6 +197,7 @@ run_command(cmd, mask, infd, outfd, a0, a1, a2) } /*VARARGS4*/ +int start_command(cmd, mask, infd, outfd, a0, a1, a2) char *cmd; int mask, infd, outfd; @@ -190,17 +225,20 @@ start_command(cmd, mask, infd, outfd, a0, a1, a2) return pid; } +void prepare_child(mask, infd, outfd) int mask, infd, outfd; { int i; + /* + * All file descriptors other than 0, 1, and 2 are supposed to be + * close-on-exec. + */ if (infd >= 0) dup2(infd, 0); if (outfd >= 0) dup2(outfd, 1); - for (i = getdtablesize(); --i > 2;) - close(i); for (i = 1; i <= NSIG; i++) if (mask & sigmask(i)) (void) signal(i, SIG_IGN); @@ -209,6 +247,7 @@ prepare_child(mask, infd, outfd) (void) sigsetmask(0); } +int wait_command(pid) int pid; { @@ -220,16 +259,7 @@ wait_command(pid) return 0; } -struct child { - int pid; - char done; - char free; - union wait status; - struct child *link; -}; -static struct child *child; - -struct child * +static struct child * findchild(pid) int pid; { @@ -247,6 +277,7 @@ findchild(pid) return *cpp; } +static void delchild(cp) register struct child *cp; { @@ -258,13 +289,16 @@ delchild(cp) free((char *) cp); } -sigchild() +void +sigchild(signo) + int signo; { int pid; union wait status; register struct child *cp; - while ((pid = wait3(&status, WNOHANG, (struct timeval *)0)) > 0) { + while ((pid = + wait3((int *)&status, WNOHANG, (struct rusage *)0)) > 0) { cp = findchild(pid); if (cp->free) delchild(cp); @@ -280,6 +314,7 @@ union wait wait_status; /* * Wait for a specific child to die. */ +int wait_child(pid) int pid; { @@ -297,6 +332,7 @@ wait_child(pid) /* * Mark a child as don't care. */ +void free_child(pid) int pid; {