|
|
1.1 ! root 1: /* ! 2: Copyright (C) 1993 Free Software Foundation ! 3: ! 4: This file is part of the GNU IO Library. This library is free ! 5: software; you can redistribute it and/or modify it under the ! 6: terms of the GNU General Public License as published by the ! 7: Free Software Foundation; either version 2, or (at your option) ! 8: any later version. ! 9: ! 10: This library is distributed in the hope that it will be useful, ! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 13: GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with GNU CC; see the file COPYING. If not, write to ! 17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 18: ! 19: As a special exception, if you link this library with files ! 20: compiled with a GNU compiler to produce an executable, this does not cause ! 21: the resulting executable to be covered by the GNU General Public License. ! 22: This exception does not however invalidate any other reasons why ! 23: the executable file might be covered by the GNU General Public License. */ ! 24: ! 25: /* written by Per Bothner ([email protected]) */ ! 26: ! 27: #include "libioP.h" ! 28: ! 29: #if _IO_HAVE_SYS_WAIT ! 30: #include <signal.h> ! 31: #include <unistd.h> ! 32: #ifdef __STDC__ ! 33: /* This is now provided by gcc's fixproto. */ ! 34: #include <stdlib.h> ! 35: #endif ! 36: #include <errno.h> ! 37: #ifndef errno ! 38: extern int errno; ! 39: #endif ! 40: #include <sys/wait.h> ! 41: ! 42: #ifndef _IO_fork ! 43: #define _IO_fork vfork /* defined in libiberty, if needed */ ! 44: _IO_pid_t _IO_fork(); ! 45: #endif ! 46: ! 47: #endif /* _IO_HAVE_SYS_WAIT */ ! 48: ! 49: #ifndef _IO_pipe ! 50: #define _IO_pipe pipe ! 51: extern int _IO_pipe(); ! 52: #endif ! 53: ! 54: #ifndef _IO_dup2 ! 55: #define _IO_dup2 dup2 ! 56: extern int _IO_dup2(); ! 57: #endif ! 58: ! 59: #ifndef _IO_waitpid ! 60: #define _IO_waitpid waitpid ! 61: #endif ! 62: ! 63: #ifndef _IO_execl ! 64: #define _IO_execl execl ! 65: #endif ! 66: #ifndef _IO__exit ! 67: #define _IO__exit _exit ! 68: #endif ! 69: ! 70: struct _IO_proc_file ! 71: { ! 72: struct _IO_FILE_plus _file; ! 73: /* Following fields must match those in class procbuf (procbuf.h) */ ! 74: _IO_pid_t _pid; ! 75: struct _IO_proc_file *_next; ! 76: }; ! 77: typedef struct _IO_proc_file _IO_proc_file; ! 78: ! 79: static struct _IO_proc_file *proc_file_chain = NULL; ! 80: ! 81: _IO_FILE * ! 82: _IO_proc_open(fp, command, mode) ! 83: _IO_FILE* fp; ! 84: const char *command; ! 85: const char *mode; ! 86: { ! 87: #if _IO_HAVE_SYS_WAIT ! 88: int read_or_write; ! 89: int pipe_fds[2]; ! 90: int parent_end, child_end; ! 91: _IO_pid_t child_pid; ! 92: if (_IO_file_is_open(fp)) ! 93: return NULL; ! 94: if (_IO_pipe(pipe_fds) < 0) ! 95: return NULL; ! 96: if (mode[0] == 'r') ! 97: { ! 98: parent_end = pipe_fds[0]; ! 99: child_end = pipe_fds[1]; ! 100: read_or_write = _IO_NO_WRITES; ! 101: } ! 102: else ! 103: { ! 104: parent_end = pipe_fds[1]; ! 105: child_end = pipe_fds[0]; ! 106: read_or_write = _IO_NO_READS; ! 107: } ! 108: ((_IO_proc_file*)fp)->_pid = child_pid = _IO_fork(); ! 109: if (child_pid == 0) ! 110: { ! 111: int child_std_end = mode[0] == 'r' ? 1 : 0; ! 112: _IO_close(parent_end); ! 113: if (child_end != child_std_end) ! 114: { ! 115: _IO_dup2(child_end, child_std_end); ! 116: _IO_close(child_end); ! 117: } ! 118: /* Posix.2: "popen() shall ensure that any streams from previous ! 119: popen() calls that remain open in the parent process are closed ! 120: in the new child process." */ ! 121: while (proc_file_chain) ! 122: { ! 123: _IO_close (_IO_fileno ((_IO_FILE *) proc_file_chain)); ! 124: proc_file_chain = proc_file_chain->_next; ! 125: } ! 126: ! 127: _IO_execl("/bin/sh", "sh", "-c", command, NULL); ! 128: _IO__exit(127); ! 129: } ! 130: _IO_close(child_end); ! 131: if (child_pid < 0) ! 132: { ! 133: _IO_close(parent_end); ! 134: return NULL; ! 135: } ! 136: _IO_fileno(fp) = parent_end; ! 137: ! 138: /* Link into proc_file_chain. */ ! 139: ((_IO_proc_file*)fp)->_next = proc_file_chain; ! 140: proc_file_chain = (_IO_proc_file*)fp; ! 141: ! 142: fp->_IO_file_flags ! 143: = read_or_write | (fp->_IO_file_flags & ~(_IO_NO_READS|_IO_NO_WRITES)); ! 144: return fp; ! 145: #else /* !_IO_HAVE_SYS_WAIT */ ! 146: return NULL; ! 147: #endif ! 148: } ! 149: ! 150: _IO_FILE * ! 151: _IO_popen(command, mode) ! 152: const char *command; ! 153: const char *mode; ! 154: { ! 155: _IO_proc_file *fpx = (_IO_proc_file*)malloc(sizeof(_IO_proc_file)); ! 156: _IO_FILE *fp = (_IO_FILE*)fpx; ! 157: if (fp == NULL) ! 158: return NULL; ! 159: _IO_init(fp, 0); ! 160: fp->_jumps = &_IO_proc_jumps; ! 161: _IO_file_init(fp); ! 162: ((struct _IO_FILE_plus*)fp)->_vtable = NULL; ! 163: if (_IO_proc_open (fp, command, mode) != NULL) ! 164: return fp; ! 165: free (fpx); ! 166: return NULL; ! 167: } ! 168: ! 169: int ! 170: _IO_proc_close(fp) ! 171: _IO_FILE *fp; ! 172: { ! 173: /* This is not name-space clean. FIXME! */ ! 174: #if _IO_HAVE_SYS_WAIT ! 175: int wstatus; ! 176: _IO_proc_file **ptr = &proc_file_chain; ! 177: _IO_pid_t wait_pid; ! 178: int status = _IO_close(_IO_fileno(fp)); ! 179: ! 180: /* Unlink from proc_file_chain. */ ! 181: for ( ; *ptr != NULL; ptr = &(*ptr)->_next) ! 182: { ! 183: if (*ptr == (_IO_proc_file*)fp) ! 184: { ! 185: *ptr = (*ptr)->_next; ! 186: break; ! 187: } ! 188: } ! 189: ! 190: if (status < 0) ! 191: return status; ! 192: /* POSIX.2 Rationale: "Some historical implementations either block ! 193: or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting ! 194: for the child process to terminate. Since this behavior is not ! 195: described in POSIX.2, such implementations are not conforming." */ ! 196: do ! 197: { ! 198: wait_pid = _IO_waitpid (((_IO_proc_file*)fp)->_pid, &wstatus, 0); ! 199: } while (wait_pid == -1 && errno == EINTR); ! 200: if (wait_pid == -1) ! 201: return -1; ! 202: return wstatus; ! 203: #else /* !_IO_HAVE_SYS_WAIT */ ! 204: return -1; ! 205: #endif ! 206: } ! 207: ! 208: struct _IO_jump_t _IO_proc_jumps = { ! 209: _IO_file_overflow, ! 210: _IO_file_underflow, ! 211: _IO_file_xsputn, ! 212: _IO_default_xsgetn, ! 213: _IO_file_read, ! 214: _IO_file_write, ! 215: _IO_file_doallocate, ! 216: _IO_default_pbackfail, ! 217: _IO_file_setbuf, ! 218: _IO_file_sync, ! 219: _IO_file_finish, ! 220: _IO_proc_close, ! 221: _IO_file_stat, ! 222: _IO_file_seek, ! 223: _IO_file_seekoff, ! 224: _IO_default_seekpos, ! 225: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.