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 ---