source: trunk/minix/lib/other/popen.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 2.3 KB
Line 
1/*
2 * popen - open a pipe
3 */
4/* $Header: /cvsup/minix/src/lib/other/popen.c,v 1.1.1.1 2005/04/21 14:56:27 beng Exp $ */
5
6#include <sys/types.h>
7#include <limits.h>
8#include <errno.h>
9#include <signal.h>
10#include <stdio.h>
11
12#if defined(__BSD4_2)
13union wait {
14 int w_status;
15};
16typedef union wait wait_arg;
17#else
18typedef int wait_arg;
19#endif /* __BSD4_2 */
20
21#include "../stdio/loc_incl.h"
22
23#ifdef _ANSI
24int _close(int d);
25int _dup2(int oldd, int newd); /* not present in System 5 */
26int _execl(const char *name, const char *_arg, ... );
27pid_t _fork(void);
28int _pipe(int fildes[2]);
29pid_t _wait(wait_arg *status);
30void _exit(int status);
31#endif
32
33static int pids[OPEN_MAX];
34
35FILE *
36popen(command, type)
37_CONST char *command;
38_CONST char *type;
39{
40 int piped[2];
41 int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
42 int pid;
43
44 if (Xtype == 2 ||
45 _pipe(piped) < 0 ||
46 (pid = _fork()) < 0) return 0;
47
48 if (pid == 0) {
49 /* child */
50 register int *p;
51
52 for (p = pids; p < &pids[OPEN_MAX]; p++) {
53 if (*p) _close((int)(p - pids));
54 }
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() ??? */
60 }
61
62 pids[piped[Xtype]] = pid;
63 _close(piped[!Xtype]);
64 return fdopen(piped[Xtype], type);
65}
66
67#if defined(__BSD4_2)
68#define ret_val status.w_status
69#else
70#define ret_val status
71#endif
72
73int
74pclose(stream)
75FILE *stream;
76{
77 int fd = fileno(stream);
78 wait_arg status;
79 int wret;
80
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;
91 }
92 if (wret == -1) ret_val = -1;
93 signal(SIGINT, intsave);
94 signal(SIGQUIT, quitsave);
95 pids[fd] = 0;
96 return ret_val;
97}
98
99#if defined(__USG)
100int _dup(int fildes);
101
102static int
103_dup2(oldd, newd)
104int oldd, newd;
105{
106 int i = 0, fd, tmp;
107 int fdbuf[_NFILES];
108
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;
114 }
115 tmp = errno;
116 while (--i >= 0) {
117 _close(fdbuf[i]);
118 }
119 errno = tmp;
120 return -(fd == -1);
121}
122#endif /* __USG */
Note: See TracBrowser for help on using the repository browser.