Changeset 202 for trunk/base
- Timestamp:
- Aug 19, 2002, 10:09:56 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/base/Tcl/port1.0/Pextlib.c
r201 r202 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 17 8 #include <tcl.h> 18 9 … … 38 29 } 39 30 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 avoid92 * writing to pdes[1], which might corrupt the93 * parent's copy. This isn't good enough in94 * general, since the _exit() is no return, so95 * the compiler is free to corrupt all the local96 * 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 141 31 int SystemCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) 142 32 { … … 144 34 char *cmdstring, *p; 145 35 FILE *pipe; 146 147 36 int i, cmdlen, cmdlenavail; 148 37 cmdlen = cmdlenavail = BUFSIZ; … … 206 95 } 207 96 208 /*pipe = popen(cmdstring, "r");*/ 209 pipe = dup2popen(cmdstring, "r"); 210 /*Gutted the popen code...*/ 97 pipe = popen(cmdstring, "r"); 211 98 if (p != NULL) 212 99 free(cmdstring);
Note: See TracChangeset
for help on using the changeset viewer.