4 /* $Id: popen.c,v 1.5 1994/06/24 11:45:35 ceriel Exp $ */
13 typedef union wait wait_arg;
17 #include "../stdio/loc_incl.h"
23 int _dup2(int oldd, int newd); /* not present in System 5 */
24 int _execl(const char *name, ... );
26 int _pipe(int fildes[2]);
27 int _wait(wait_arg *status);
28 void _exit(int status);
30 static int pids[FOPEN_MAX];
33 popen(const char *command, const char *type)
36 int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
41 (pid = _fork()) < 0) return 0;
47 for (p = pids; p < &pids[ FOPEN_MAX]; p++) {
48 if (*p) _close(p - pids);
51 _dup2(piped[!Xtype], !Xtype);
52 _close(piped[!Xtype]);
53 _execl("/bin/sh", "sh", "-c", command, (char *) 0);
54 _exit(127); /* like system() ??? */
57 pids[piped[Xtype]] = pid;
58 _close(piped[!Xtype]);
59 return fdopen(piped[Xtype], type);
63 #define ret_val status.w_status
65 #define ret_val status
71 int fd = fileno(stream);
74 void (*intsave)(int) = signal(SIGINT, SIG_IGN);
75 void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
78 while ((wret = _wait(&status)) != -1) {
79 if (wret == pids[fd]) break;
81 if (wret == -1) ret_val = -1;
82 signal(SIGINT, intsave);
83 signal(SIGQUIT, quitsave);
92 _dup2(int oldd, int newd)
97 /* ignore the error on the close() */
98 tmp = errno; (void) _close(newd); errno = tmp;
99 while ((fd = _dup(oldd)) != newd) {