at_wini also needs a pci_reserve() for the pci compatability device, if
[minix3.git] / lib / other / popen.c
blob7f117322e3e1274f304c21cd40ebde019b06593c
1 /*
2 * popen - open a pipe
3 */
4 /* $Header$ */
6 #include <sys/types.h>
7 #include <limits.h>
8 #include <errno.h>
9 #include <signal.h>
10 #include <stdio.h>
12 #if defined(__BSD4_2)
13 union wait {
14 int w_status;
16 typedef union wait wait_arg;
17 #else
18 typedef int wait_arg;
19 #endif /* __BSD4_2 */
21 #include "../stdio/loc_incl.h"
23 #ifdef _ANSI
24 int _close(int d);
25 int _dup2(int oldd, int newd); /* not present in System 5 */
26 int _execl(const char *name, const char *_arg, ... );
27 pid_t _fork(void);
28 int _pipe(int fildes[2]);
29 pid_t _wait(wait_arg *status);
30 void _exit(int status);
31 #endif
33 static int pids[OPEN_MAX];
35 FILE *
36 popen(command, type)
37 _CONST char *command;
38 _CONST char *type;
40 int piped[2];
41 int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
42 int pid;
44 if (Xtype == 2 ||
45 _pipe(piped) < 0 ||
46 (pid = _fork()) < 0) return 0;
48 if (pid == 0) {
49 /* child */
50 register int *p;
52 for (p = pids; p < &pids[OPEN_MAX]; p++) {
53 if (*p) _close((int)(p - pids));
55 _close(piped[Xtype]);
56 _dup2(piped[!Xtype], !Xtype);
57 _close(piped[!Xtype]);
58 _execl("/bin/sh", "sh", "-c", command, (char *) 0);
59 _exit(127); /* like system() ??? */
62 pids[piped[Xtype]] = pid;
63 _close(piped[!Xtype]);
64 return fdopen(piped[Xtype], type);
67 #if defined(__BSD4_2)
68 #define ret_val status.w_status
69 #else
70 #define ret_val status
71 #endif
73 int
74 pclose(stream)
75 FILE *stream;
77 int fd = fileno(stream);
78 wait_arg status;
79 int wret;
81 #ifdef _ANSI
82 void (*intsave)(int) = signal(SIGINT, SIG_IGN);
83 void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
84 #else
85 void (*intsave)() = signal(SIGINT, SIG_IGN);
86 void (*quitsave)() = signal(SIGQUIT, SIG_IGN);
87 #endif
88 fclose(stream);
89 while ((wret = _wait(&status)) != -1) {
90 if (wret == pids[fd]) break;
92 if (wret == -1) ret_val = -1;
93 signal(SIGINT, intsave);
94 signal(SIGQUIT, quitsave);
95 pids[fd] = 0;
96 return ret_val;
99 #if defined(__USG)
100 int _dup(int fildes);
102 static int
103 _dup2(oldd, newd)
104 int oldd, newd;
106 int i = 0, fd, tmp;
107 int fdbuf[_NFILES];
109 /* ignore the error on the close() */
110 tmp = errno; (void) _close(newd); errno = tmp;
111 while ((fd = _dup(oldd)) != newd) {
112 if (fd == -1) break;
113 fdbuf[i++] = fd;
115 tmp = errno;
116 while (--i >= 0) {
117 _close(fdbuf[i]);
119 errno = tmp;
120 return -(fd == -1);
122 #endif /* __USG */