vm: fix a null dereference on out-of-memory
[minix.git] / lib / libc / gen / minix / popen.c
blob3bd48fc46805cba83ec291daf05132ad1b51130a
1 /*
2 * popen - open a pipe
3 */
4 /* $Header$ */
5 #include <sys/cdefs.h>
6 #include "namespace.h"
8 #ifdef __weak_alias
9 __weak_alias(popen, _popen)
10 __weak_alias(pclose, _pclose)
11 #endif
13 #include <sys/types.h>
14 #include <limits.h>
15 #include <errno.h>
16 #include <signal.h>
17 #include <stdio.h>
19 #if defined(__BSD4_2)
20 union wait {
21 int w_status;
23 typedef union wait wait_arg;
24 #else
25 typedef int wait_arg;
26 #endif /* __BSD4_2 */
28 int _close(int d);
29 int _dup2(int oldd, int newd); /* not present in System 5 */
30 int _execl(const char *name, const char *_arg, ... );
31 pid_t _fork(void);
32 int _pipe(int fildes[2]);
33 pid_t _wait(wait_arg *status);
34 void _exit(int status);
36 static int pids[OPEN_MAX];
38 FILE *
39 popen(command, type)
40 const char *command;
41 const char *type;
43 int piped[2];
44 int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
45 int pid;
47 if (Xtype == 2 ||
48 _pipe(piped) < 0 ||
49 (pid = _fork()) < 0) return 0;
51 if (pid == 0) {
52 /* child */
53 register int *p;
55 for (p = pids; p < &pids[OPEN_MAX]; p++) {
56 if (*p) _close((int)(p - pids));
58 _close(piped[Xtype]);
59 _dup2(piped[!Xtype], !Xtype);
60 _close(piped[!Xtype]);
61 _execl("/bin/sh", "sh", "-c", command, (char *) 0);
62 _exit(127); /* like system() ??? */
65 pids[piped[Xtype]] = pid;
66 _close(piped[!Xtype]);
67 return fdopen(piped[Xtype], type);
70 #if defined(__BSD4_2)
71 #define ret_val status.w_status
72 #else
73 #define ret_val status
74 #endif
76 int
77 pclose(stream)
78 FILE *stream;
80 int fd = fileno(stream);
81 wait_arg status;
82 int wret;
84 void (*intsave)(int) = signal(SIGINT, SIG_IGN);
85 void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
86 fclose(stream);
87 while ((wret = _wait(&status)) != -1) {
88 if (wret == pids[fd]) break;
90 if (wret == -1) ret_val = -1;
91 signal(SIGINT, intsave);
92 signal(SIGQUIT, quitsave);
93 pids[fd] = 0;
94 return ret_val;
97 #if defined(__USG)
98 int _dup(int fildes);
100 static int
101 _dup2(oldd, newd)
102 int oldd, newd;
104 int i = 0, fd, tmp;
105 int fdbuf[_NFILES];
107 /* ignore the error on the close() */
108 tmp = errno; (void) _close(newd); errno = tmp;
109 while ((fd = _dup(oldd)) != newd) {
110 if (fd == -1) break;
111 fdbuf[i++] = fd;
113 tmp = errno;
114 while (--i >= 0) {
115 _close(fdbuf[i]);
117 errno = tmp;
118 return -(fd == -1);
120 #endif /* __USG */