00001
00002
00003
00004
00005
00006 #include <sys/types.h>
00007 #include <limits.h>
00008 #include <errno.h>
00009 #include <signal.h>
00010 #include <stdio.h>
00011
00012 #if defined(__BSD4_2)
00013 union wait {
00014 int w_status;
00015 };
00016 typedef union wait wait_arg;
00017 #else
00018 typedef int wait_arg;
00019 #endif
00020
00021 #include "../stdio/loc_incl.h"
00022
00023 #ifdef _ANSI
00024 int _close(int d);
00025 int _dup2(int oldd, int newd);
00026 int _execl(const char *name, const char *_arg, ... );
00027 pid_t _fork(void);
00028 int _pipe(int fildes[2]);
00029 pid_t _wait(wait_arg *status);
00030 void _exit(int status);
00031 #endif
00032
00033 static int pids[OPEN_MAX];
00034
00035 FILE *
00036 popen(command, type)
00037 _CONST char *command;
00038 _CONST char *type;
00039 {
00040 int piped[2];
00041 int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
00042 int pid;
00043
00044 if (Xtype == 2 ||
00045 _pipe(piped) < 0 ||
00046 (pid = _fork()) < 0) return 0;
00047
00048 if (pid == 0) {
00049
00050 register int *p;
00051
00052 for (p = pids; p < &pids[OPEN_MAX]; p++) {
00053 if (*p) _close((int)(p - pids));
00054 }
00055 _close(piped[Xtype]);
00056 _dup2(piped[!Xtype], !Xtype);
00057 _close(piped[!Xtype]);
00058 _execl("/bin/sh", "sh", "-c", command, (char *) 0);
00059 _exit(127);
00060 }
00061
00062 pids[piped[Xtype]] = pid;
00063 _close(piped[!Xtype]);
00064 return fdopen(piped[Xtype], type);
00065 }
00066
00067 #if defined(__BSD4_2)
00068 #define ret_val status.w_status
00069 #else
00070 #define ret_val status
00071 #endif
00072
00073 int
00074 pclose(stream)
00075 FILE *stream;
00076 {
00077 int fd = fileno(stream);
00078 wait_arg status;
00079 int wret;
00080
00081 #ifdef _ANSI
00082 void (*intsave)(int) = signal(SIGINT, SIG_IGN);
00083 void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
00084 #else
00085 void (*intsave)() = signal(SIGINT, SIG_IGN);
00086 void (*quitsave)() = signal(SIGQUIT, SIG_IGN);
00087 #endif
00088 fclose(stream);
00089 while ((wret = _wait(&status)) != -1) {
00090 if (wret == pids[fd]) break;
00091 }
00092 if (wret == -1) ret_val = -1;
00093 signal(SIGINT, intsave);
00094 signal(SIGQUIT, quitsave);
00095 pids[fd] = 0;
00096 return ret_val;
00097 }
00098
00099 #if defined(__USG)
00100 int _dup(int fildes);
00101
00102 static int
00103 _dup2(oldd, newd)
00104 int oldd, newd;
00105 {
00106 int i = 0, fd, tmp;
00107 int fdbuf[_NFILES];
00108
00109
00110 tmp = errno; (void) _close(newd); errno = tmp;
00111 while ((fd = _dup(oldd)) != newd) {
00112 if (fd == -1) break;
00113 fdbuf[i++] = fd;
00114 }
00115 tmp = errno;
00116 while (--i >= 0) {
00117 _close(fdbuf[i]);
00118 }
00119 errno = tmp;
00120 return -(fd == -1);
00121 }
00122 #endif