2 * Copyright (c) 1995, by Sun Microsystems, Inc.
6 #pragma ident "%Z%%M% %I% %E% SMI"
7 /* from UCB 5.2 85/06/05 */
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.
19 #define tst(a,b) (*mode == 'r'? (b) : (a))
23 extern char *malloc();
24 extern int execl(), vfork(), pipe(), close(), fcntl();
26 static int *popen_pid
;
36 register int myside
, hisside
, pid
;
39 nfiles
= getdtablesize();
40 if (popen_pid
== NULL
) {
41 popen_pid
= (int *)malloc(nfiles
* sizeof *popen_pid
);
42 if (popen_pid
== NULL
)
44 for (pid
= 0; pid
< nfiles
; pid
++)
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 */
55 /* close all pipes from other popen's */
56 for (poptr
= popen_pid
; poptr
< popen_pid
+nfiles
; poptr
++) {
58 close(poptr
- popen_pid
);
62 if (hisside
!= stdio
) {
63 (void) dup2(hisside
, stdio
);
64 (void) close(hisside
);
66 (void) execl("/bin/sh", "sh", "-c", cmd
, (char *)NULL
);
74 popen_pid
[myside
] = pid
;
76 return (fdopen(myside
, mode
));
84 int pid
, status
, omask
;
86 if (popen_pid
!= NULL
) {
87 child
= popen_pid
[fileno(ptr
)];
88 popen_pid
[fileno(ptr
)] = -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
);