popen.c (10b3b54548f2290bbe8d8f88c59c28d12b7a635d) | popen.c (e9dec7758d3372e48746d32ba8c485cf89d83802) |
---|---|
1/* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software written by Ken Arnold and 6 * published in UNIX Review, Vol. 6, No. 8. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 29 unchanged lines hidden (view full) --- 38 39#include "namespace.h" 40#include <sys/param.h> 41#include <sys/queue.h> 42#include <sys/wait.h> 43 44#include <signal.h> 45#include <errno.h> | 1/* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software written by Ken Arnold and 6 * published in UNIX Review, Vol. 6, No. 8. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 29 unchanged lines hidden (view full) --- 38 39#include "namespace.h" 40#include <sys/param.h> 41#include <sys/queue.h> 42#include <sys/wait.h> 43 44#include <signal.h> 45#include <errno.h> |
46#include <fcntl.h> |
|
46#include <unistd.h> 47#include <stdio.h> 48#include <stdlib.h> 49#include <string.h> 50#include <paths.h> 51#include <pthread.h> 52#include "un-namespace.h" 53#include "libc_private.h" --- 12 unchanged lines hidden (view full) --- 66#define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&pidlist_mutex) 67 68FILE * 69popen(command, type) 70 const char *command, *type; 71{ 72 struct pid *cur; 73 FILE *iop; | 47#include <unistd.h> 48#include <stdio.h> 49#include <stdlib.h> 50#include <string.h> 51#include <paths.h> 52#include <pthread.h> 53#include "un-namespace.h" 54#include "libc_private.h" --- 12 unchanged lines hidden (view full) --- 67#define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&pidlist_mutex) 68 69FILE * 70popen(command, type) 71 const char *command, *type; 72{ 73 struct pid *cur; 74 FILE *iop; |
74 int pdes[2], pid, twoway; | 75 int pdes[2], pid, twoway, cloexec; |
75 char *argv[4]; 76 struct pid *p; 77 | 76 char *argv[4]; 77 struct pid *p; 78 |
79 cloexec = strchr(type, 'e') != NULL; |
|
78 /* 79 * Lite2 introduced two-way popen() pipes using _socketpair(). 80 * FreeBSD's pipe() is bidirectional, so we use that. 81 */ 82 if (strchr(type, '+')) { 83 twoway = 1; 84 type = "r+"; 85 } else { 86 twoway = 0; | 80 /* 81 * Lite2 introduced two-way popen() pipes using _socketpair(). 82 * FreeBSD's pipe() is bidirectional, so we use that. 83 */ 84 if (strchr(type, '+')) { 85 twoway = 1; 86 type = "r+"; 87 } else { 88 twoway = 0; |
87 if ((*type != 'r' && *type != 'w') || type[1]) | 89 if ((*type != 'r' && *type != 'w') || 90 (type[1] && (type[1] != 'e' || type[2]))) |
88 return (NULL); 89 } | 91 return (NULL); 92 } |
90 if (pipe(pdes) < 0) | 93 if ((cloexec ? pipe2(pdes, O_CLOEXEC) : pipe(pdes)) < 0) |
91 return (NULL); 92 93 if ((cur = malloc(sizeof(struct pid))) == NULL) { 94 (void)_close(pdes[0]); 95 (void)_close(pdes[1]); 96 return (NULL); 97 } 98 --- 16 unchanged lines hidden (view full) --- 115 /* 116 * The _dup2() to STDIN_FILENO is repeated to avoid 117 * writing to pdes[1], which might corrupt the 118 * parent's copy. This isn't good enough in 119 * general, since the _exit() is no return, so 120 * the compiler is free to corrupt all the local 121 * variables. 122 */ | 94 return (NULL); 95 96 if ((cur = malloc(sizeof(struct pid))) == NULL) { 97 (void)_close(pdes[0]); 98 (void)_close(pdes[1]); 99 return (NULL); 100 } 101 --- 16 unchanged lines hidden (view full) --- 118 /* 119 * The _dup2() to STDIN_FILENO is repeated to avoid 120 * writing to pdes[1], which might corrupt the 121 * parent's copy. This isn't good enough in 122 * general, since the _exit() is no return, so 123 * the compiler is free to corrupt all the local 124 * variables. 125 */ |
123 (void)_close(pdes[0]); | 126 if (!cloexec) 127 (void)_close(pdes[0]); |
124 if (pdes[1] != STDOUT_FILENO) { 125 (void)_dup2(pdes[1], STDOUT_FILENO); | 128 if (pdes[1] != STDOUT_FILENO) { 129 (void)_dup2(pdes[1], STDOUT_FILENO); |
126 (void)_close(pdes[1]); | 130 if (!cloexec) 131 (void)_close(pdes[1]); |
127 if (twoway) 128 (void)_dup2(STDOUT_FILENO, STDIN_FILENO); | 132 if (twoway) 133 (void)_dup2(STDOUT_FILENO, STDIN_FILENO); |
129 } else if (twoway && (pdes[1] != STDIN_FILENO)) | 134 } else if (twoway && (pdes[1] != STDIN_FILENO)) { |
130 (void)_dup2(pdes[1], STDIN_FILENO); | 135 (void)_dup2(pdes[1], STDIN_FILENO); |
136 if (cloexec) 137 (void)_fcntl(pdes[1], F_SETFD, 0); 138 } else if (cloexec) 139 (void)_fcntl(pdes[1], F_SETFD, 0); |
|
131 } else { 132 if (pdes[0] != STDIN_FILENO) { 133 (void)_dup2(pdes[0], STDIN_FILENO); | 140 } else { 141 if (pdes[0] != STDIN_FILENO) { 142 (void)_dup2(pdes[0], STDIN_FILENO); |
134 (void)_close(pdes[0]); 135 } 136 (void)_close(pdes[1]); | 143 if (!cloexec) 144 (void)_close(pdes[0]); 145 } else if (cloexec) 146 (void)_fcntl(pdes[0], F_SETFD, 0); 147 if (!cloexec) 148 (void)_close(pdes[1]); |
137 } 138 SLIST_FOREACH(p, &pidlist, next) 139 (void)_close(fileno(p->fp)); 140 _execve(_PATH_BSHELL, argv, environ); 141 _exit(127); 142 /* NOTREACHED */ 143 } 144 THREAD_UNLOCK(); --- 62 unchanged lines hidden --- | 149 } 150 SLIST_FOREACH(p, &pidlist, next) 151 (void)_close(fileno(p->fp)); 152 _execve(_PATH_BSHELL, argv, environ); 153 _exit(127); 154 /* NOTREACHED */ 155 } 156 THREAD_UNLOCK(); --- 62 unchanged lines hidden --- |