8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbc / libc / gen / common / popen.c
blobbb295e717a070585bf42951fb53b1641d529be84
1 /*
2 * Copyright (c) 1995, by Sun Microsystems, Inc.
3 * All rights reserved.
4 */
6 #pragma ident "%Z%%M% %I% %E% SMI"
7 /* from UCB 5.2 85/06/05 */
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
15 #include <stdio.h>
16 #include <signal.h>
17 #include <vfork.h>
19 #define tst(a,b) (*mode == 'r'? (b) : (a))
20 #define RDR 0
21 #define WTR 1
23 extern char *malloc();
24 extern int execl(), vfork(), pipe(), close(), fcntl();
26 static int *popen_pid;
27 static int nfiles;
29 FILE *
30 popen(cmd,mode)
31 char *cmd;
32 char *mode;
34 int p[2];
35 register int *poptr;
36 register int myside, hisside, pid;
38 if (nfiles <= 0)
39 nfiles = getdtablesize();
40 if (popen_pid == NULL) {
41 popen_pid = (int *)malloc(nfiles * sizeof *popen_pid);
42 if (popen_pid == NULL)
43 return (NULL);
44 for (pid = 0; pid < nfiles; pid++)
45 popen_pid[pid] = -1;
47 if (pipe(p) < 0)
48 return (NULL);
49 myside = tst(p[WTR], p[RDR]);
50 hisside = tst(p[RDR], p[WTR]);
51 if ((pid = vfork()) == 0) {
52 /* myside and hisside reverse roles in child */
53 int stdio;
55 /* close all pipes from other popen's */
56 for (poptr = popen_pid; poptr < popen_pid+nfiles; poptr++) {
57 if(*poptr >= 0)
58 close(poptr - popen_pid);
60 stdio = tst(0, 1);
61 (void) close(myside);
62 if (hisside != stdio) {
63 (void) dup2(hisside, stdio);
64 (void) close(hisside);
66 (void) execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
67 _exit(127);
69 if (pid == -1) {
70 close(myside);
71 close(hisside);
72 return (NULL);
74 popen_pid[myside] = pid;
75 close(hisside);
76 return (fdopen(myside, mode));
79 int
80 pclose(ptr)
81 FILE *ptr;
83 int child = -1;
84 int pid, status, omask;
86 if (popen_pid != NULL) {
87 child = popen_pid[fileno(ptr)];
88 popen_pid[fileno(ptr)] = -1;
90 fclose(ptr);
91 if (child == -1)
92 return (-1);
93 omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
94 while ((pid = waitpid(child, &status, 0)) != child && pid != -1)
96 (void) sigsetmask(omask);
97 return (pid == -1 ? -1 : status);