]>
Commit | Line | Data |
---|---|---|
eb1cde05 | 1 | --- popen.c.orig 2003-05-20 15:21:02.000000000 -0700 |
224c7076 A |
2 | +++ popen.c 2005-09-14 15:53:35.000000000 -0700 |
3 | @@ -43,7 +43,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop | |
59e0d9fe A |
4 | #include "namespace.h" |
5 | #include <sys/param.h> | |
6 | #include <sys/wait.h> | |
224c7076 | 7 | - |
59e0d9fe | 8 | +#include <sys/socket.h> |
224c7076 | 9 | +#include <wchar.h> /* fwide() */ |
59e0d9fe A |
10 | #include <signal.h> |
11 | #include <errno.h> | |
224c7076 A |
12 | #include <unistd.h> |
13 | @@ -55,11 +56,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/pop | |
9385eb3d A |
14 | #include "un-namespace.h" |
15 | #include "libc_private.h" | |
16 | ||
17 | -extern char **environ; | |
18 | +#include <crt_externs.h> | |
19 | +#define environ (*_NSGetEnviron()) | |
20 | ||
59e0d9fe | 21 | +/* 3516149 - store file descriptor and use that to close to prevent blocking */ |
9385eb3d A |
22 | static struct pid { |
23 | struct pid *next; | |
59e0d9fe A |
24 | FILE *fp; |
25 | + int fd; | |
26 | pid_t pid; | |
27 | } *pidlist; | |
28 | static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; | |
224c7076 | 29 | @@ -77,20 +81,24 @@ popen(command, type) |
59e0d9fe A |
30 | char *argv[4]; |
31 | struct pid *p; | |
32 | ||
33 | - /* | |
34 | - * Lite2 introduced two-way popen() pipes using _socketpair(). | |
35 | - * FreeBSD's pipe() is bidirectional, so we use that. | |
36 | - */ | |
224c7076 A |
37 | - if (strchr(type, '+')) { |
38 | + if (type == NULL) { | |
39 | + errno = EINVAL; | |
40 | + return (NULL); | |
41 | + } | |
42 | + if (strcmp(type, "r+") == 0) { | |
59e0d9fe A |
43 | twoway = 1; |
44 | type = "r+"; | |
45 | + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pdes) < 0) | |
46 | + return (NULL); | |
47 | } else { | |
48 | twoway = 0; | |
224c7076 A |
49 | - if ((*type != 'r' && *type != 'w') || type[1]) |
50 | + if ((*type != 'r' && *type != 'w') || type[1]) { | |
51 | + errno = EINVAL; | |
59e0d9fe | 52 | return (NULL); |
59e0d9fe | 53 | } |
224c7076 A |
54 | if (pipe(pdes) < 0) |
55 | return (NULL); | |
56 | + } | |
59e0d9fe A |
57 | |
58 | if ((cur = malloc(sizeof(struct pid))) == NULL) { | |
59 | (void)_close(pdes[0]); | |
224c7076 | 60 | @@ -104,7 +112,7 @@ popen(command, type) |
eb1cde05 A |
61 | argv[3] = NULL; |
62 | ||
63 | THREAD_LOCK(); | |
64 | - switch (pid = vfork()) { | |
65 | + switch (pid = fork()) { | |
66 | case -1: /* Error. */ | |
67 | THREAD_UNLOCK(); | |
68 | (void)_close(pdes[0]); | |
224c7076 | 69 | @@ -138,7 +146,7 @@ popen(command, type) |
59e0d9fe A |
70 | (void)_close(pdes[1]); |
71 | } | |
72 | for (p = pidlist; p; p = p->next) { | |
73 | - (void)_close(fileno(p->fp)); | |
74 | + (void)_close(p->fd); | |
75 | } | |
76 | _execve(_PATH_BSHELL, argv, environ); | |
77 | _exit(127); | |
224c7076 | 78 | @@ -149,9 +157,11 @@ popen(command, type) |
59e0d9fe A |
79 | /* Parent; assume fdopen can't fail. */ |
80 | if (*type == 'r') { | |
81 | iop = fdopen(pdes[0], type); | |
82 | + cur->fd = pdes[0]; | |
83 | (void)_close(pdes[1]); | |
84 | } else { | |
85 | iop = fdopen(pdes[1], type); | |
86 | + cur->fd = pdes[1]; | |
87 | (void)_close(pdes[0]); | |
88 | } | |
89 | ||
224c7076 A |
90 | @@ -162,7 +172,7 @@ popen(command, type) |
91 | cur->next = pidlist; | |
92 | pidlist = cur; | |
93 | THREAD_UNLOCK(); | |
94 | - | |
95 | + fwide(iop, -1); /* byte stream */ | |
96 | return (iop); | |
97 | } | |
98 |