Changeset 201 for trunk/base
- Timestamp:
- Aug 19, 2002, 2:38:55 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/base/Tcl/port1.0/Pextlib.c
r195 r201 6 6 #include <sys/file.h> 7 7 #include <sys/types.h> 8 #include <sys/param.h> 9 #include <sys/wait.h> 10 #include <sys/socket.h> 11 #include <signal.h> 12 #include <unistd.h> 13 #include <paths.h> 14 15 #include <crt_externs.h> 16 8 17 #include <tcl.h> 9 18 … … 29 38 } 30 39 40 #define environ *(_NSGetEnviron()) 41 static struct pid { 42 struct pid *next; 43 FILE *fp; 44 pid_t pid; 45 } *pidlist; 46 47 FILE * 48 dup2popen (command, type) /*stderr and stdout together in the output*/ 49 const char * command, *type; 50 { 51 struct pid *cur; 52 FILE *iop; 53 int pdes[2], pid, twoway; 54 char *argv[4]; 55 struct pid *p; 56 57 if (strchr(type, '+')) { 58 twoway = 1; 59 type = "r+"; 60 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pdes) < 0) 61 return (NULL); 62 } else { 63 twoway = 0; 64 if ((*type != 'r' && *type != 'w') || type[1]) 65 return (NULL); 66 } 67 if (pipe(pdes) < 0) 68 return (NULL); 69 70 if ((cur = malloc(sizeof(struct pid))) == NULL) { 71 (void)close(pdes[0]); 72 (void)close(pdes[1]); 73 return (NULL); 74 } 75 76 argv[0] = "sh"; 77 argv[1] = "-c"; 78 argv[2] = (char *)command; 79 argv[3] = NULL; 80 81 switch (pid = vfork()) { 82 case -1: /* Error. */ 83 (void)close(pdes[0]); 84 (void)close(pdes[1]); 85 free(cur); 86 return (NULL); 87 /* NOTREACHED */ 88 case 0: /* Child. */ 89 if (*type == 'r') { 90 /* 91 * The _dup2() to STDIN_FILENO is repeated to avoid 92 * writing to pdes[1], which might corrupt the 93 * parent's copy. This isn't good enough in 94 * general, since the _exit() is no return, so 95 * the compiler is free to corrupt all the local 96 * variables. 97 */ 98 (void)close(pdes[0]); 99 if (pdes[1] != STDOUT_FILENO) { 100 (void)dup2(pdes[1], STDOUT_FILENO); 101 (void)close(pdes[1]); 102 if (twoway) 103 (void)dup2(STDOUT_FILENO, STDIN_FILENO); 104 } else if (twoway && (pdes[1] != STDIN_FILENO)) 105 (void)dup2(pdes[1], STDIN_FILENO); 106 } else { 107 if (pdes[0] != STDIN_FILENO) { 108 (void)dup2(pdes[0], STDIN_FILENO); 109 (void)close(pdes[0]); 110 } 111 (void)close(pdes[1]); 112 } 113 for (p = pidlist; p; p = p->next) { 114 (void)close(fileno(p->fp)); 115 } 116 (void)dup2(STDOUT_FILENO,STDERR_FILENO); 117 execve(_PATH_BSHELL, argv, environ); 118 _exit(127); 119 /* NOTREACHED */ 120 } 121 122 /* Parent; assume fdopen can't fail. */ 123 if (*type == 'r') { 124 iop = fdopen(pdes[0], type); 125 (void)close(pdes[1]); 126 } else { 127 iop = fdopen(pdes[1], type); 128 (void)close(pdes[0]); 129 } 130 131 /* Link into list of file descriptors. */ 132 cur->fp = iop; 133 cur->pid = pid; 134 cur->next = pidlist; 135 pidlist = cur; 136 137 return (iop); 138 } 139 140 31 141 int SystemCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) 32 142 { … … 34 144 char *cmdstring, *p; 35 145 FILE *pipe; 146 36 147 int i, cmdlen, cmdlenavail; 37 148 cmdlen = cmdlenavail = BUFSIZ; … … 95 206 } 96 207 97 pipe = popen(cmdstring, "r"); 208 /*pipe = popen(cmdstring, "r");*/ 209 pipe = dup2popen(cmdstring, "r"); 210 /*Gutted the popen code...*/ 98 211 if (p != NULL) 99 212 free(cmdstring);
Note: See TracChangeset
for help on using the changeset viewer.