[BZ #9895]
[glibc.git] / libio / iopopen.c
blob1a5cc0f59262df51f31527f4e2189e8bf56d79ae
1 /* Copyright (C) 1993, 1997-2002, 2003, 2004, 2007, 2008
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Per Bothner <bothner@cygnus.com>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 As a special exception, if you link the code in this file with
22 files compiled with a GNU compiler to produce an executable,
23 that does not cause the resulting executable to be covered by
24 the GNU Lesser General Public License. This exception does not
25 however invalidate any other reasons why the executable file
26 might be covered by the GNU Lesser General Public License.
27 This exception applies to code released by its copyright holders
28 in files containing the exception. */
30 #ifndef _POSIX_SOURCE
31 # define _POSIX_SOURCE
32 #endif
33 #include "libioP.h"
34 #if _IO_HAVE_SYS_WAIT
35 #include <signal.h>
36 #include <unistd.h>
37 #ifdef __STDC__
38 #include <stdlib.h>
39 #endif
40 #ifdef _LIBC
41 # include <unistd.h>
42 # include <shlib-compat.h>
43 # include <not-cancel.h>
44 #endif
45 #include <sys/types.h>
46 #include <sys/wait.h>
47 #include <kernel-features.h>
49 #ifndef _IO_fork
50 #ifdef _LIBC
51 #define _IO_fork __fork
52 #else
53 #define _IO_fork fork /* defined in libiberty, if needed */
54 #endif
55 extern _IO_pid_t _IO_fork (void) __THROW;
56 #endif
58 #endif /* _IO_HAVE_SYS_WAIT */
60 #ifndef _IO_dup2
61 #ifdef _LIBC
62 #define _IO_dup2 __dup2
63 #else
64 #define _IO_dup2 dup2
65 #endif
66 extern int _IO_dup2 (int fd, int fd2) __THROW;
67 #endif
69 #ifndef _IO_waitpid
70 #ifdef _LIBC
71 #define _IO_waitpid waitpid_not_cancel
72 #else
73 #define _IO_waitpid waitpid
74 #endif
75 #endif
77 #ifndef _IO_execl
78 #define _IO_execl execl
79 #endif
80 #ifndef _IO__exit
81 #define _IO__exit _exit
82 #endif
84 #ifndef _IO_close
85 #ifdef _LIBC
86 #define _IO_close close_not_cancel
87 #else
88 #define _IO_close close
89 #endif
90 #endif
92 struct _IO_proc_file
94 struct _IO_FILE_plus file;
95 /* Following fields must match those in class procbuf (procbuf.h) */
96 _IO_pid_t pid;
97 struct _IO_proc_file *next;
99 typedef struct _IO_proc_file _IO_proc_file;
101 static const struct _IO_jump_t _IO_proc_jumps;
103 static struct _IO_proc_file *proc_file_chain;
105 #ifdef _IO_MTSAFE_IO
106 static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer;
108 static void
109 unlock (void *not_used)
111 _IO_lock_unlock (proc_file_chain_lock);
113 #endif
115 _IO_FILE *
116 _IO_new_proc_open (fp, command, mode)
117 _IO_FILE *fp;
118 const char *command;
119 const char *mode;
121 #if _IO_HAVE_SYS_WAIT
122 int read_or_write;
123 int parent_end, child_end;
124 int pipe_fds[2];
125 _IO_pid_t child_pid;
127 int do_read = 0;
128 int do_write = 0;
129 int do_cloexec = 0;
130 while (*mode != '\0')
131 switch (*mode++)
133 case 'r':
134 do_read = 1;
135 break;
136 case 'w':
137 do_write = 1;
138 break;
139 case 'e':
140 do_cloexec = 1;
141 break;
142 default:
143 errout:
144 __set_errno (EINVAL);
145 return NULL;
148 if ((do_read ^ do_write) == 0)
149 goto errout;
151 if (_IO_file_is_open (fp))
152 return NULL;
154 #ifdef O_CLOEXEC
155 # ifndef __ASSUME_PIPE2
156 if (__have_pipe2 >= 0)
157 # endif
159 int r = __pipe2 (pipe_fds, O_CLOEXEC);
160 # ifndef __ASSUME_PIPE2
161 if (__have_pipe2 == 0)
162 __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1;
164 if (__have_pipe2 > 0)
165 # endif
166 if (r < 0)
167 return NULL;
169 #endif
170 #ifndef __ASSUME_PIPE2
171 # ifdef O_CLOEXEC
172 if (__have_pipe2 < 0)
173 # endif
174 if (__pipe (pipe_fds) < 0)
175 return NULL;
176 #endif
178 if (do_read)
180 parent_end = pipe_fds[0];
181 child_end = pipe_fds[1];
182 read_or_write = _IO_NO_WRITES;
184 else
186 parent_end = pipe_fds[1];
187 child_end = pipe_fds[0];
188 read_or_write = _IO_NO_READS;
191 ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
192 if (child_pid == 0)
194 int child_std_end = do_read ? 1 : 0;
195 struct _IO_proc_file *p;
197 #ifndef __ASSUME_PIPE2
198 /* If we have pipe2 the descriptor is marked for close-on-exec. */
199 _IO_close (parent_end);
200 #endif
201 if (child_end != child_std_end)
203 _IO_dup2 (child_end, child_std_end);
204 #ifndef __ASSUME_PIPE2
205 _IO_close (child_end);
206 #endif
208 #ifdef O_CLOEXEC
209 else
211 /* The descriptor is already the one we will use. But it must
212 not be marked close-on-exec. Undo the effects. */
213 # ifndef __ASSUME_PIPE2
214 if (__have_pipe2 > 0)
215 # endif
216 __fcntl (child_end, F_SETFD, 0);
218 #endif
219 /* POSIX.2: "popen() shall ensure that any streams from previous
220 popen() calls that remain open in the parent process are closed
221 in the new child process." */
222 for (p = proc_file_chain; p; p = p->next)
224 int fd = _IO_fileno ((_IO_FILE *) p);
226 /* If any stream from previous popen() calls has fileno
227 child_std_end, it has been already closed by the dup2 syscall
228 above. */
229 if (fd != child_std_end)
230 _IO_close (fd);
233 _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
234 _IO__exit (127);
236 _IO_close (child_end);
237 if (child_pid < 0)
239 _IO_close (parent_end);
240 return NULL;
243 if (do_cloexec)
245 #ifndef __ASSUME_PIPE2
246 # ifdef O_CLOEXEC
247 if (__have_pipe2 < 0)
248 # endif
249 __fcntl (parent_end, F_SETFD, FD_CLOEXEC);
250 #endif
252 else
254 #ifdef O_CLOEXEC
255 /* Undo the effects of the pipe2 call which set the
256 close-on-exec flag. */
257 # ifndef __ASSUME_PIPE2
258 if (__have_pipe2 > 0)
259 # endif
260 __fcntl (parent_end, F_SETFD, 0);
261 #endif
264 _IO_fileno (fp) = parent_end;
266 /* Link into proc_file_chain. */
267 #ifdef _IO_MTSAFE_IO
268 _IO_cleanup_region_start_noarg (unlock);
269 _IO_lock_lock (proc_file_chain_lock);
270 #endif
271 ((_IO_proc_file *) fp)->next = proc_file_chain;
272 proc_file_chain = (_IO_proc_file *) fp;
273 #ifdef _IO_MTSAFE_IO
274 _IO_lock_unlock (proc_file_chain_lock);
275 _IO_cleanup_region_end (0);
276 #endif
278 _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
279 return fp;
280 #else /* !_IO_HAVE_SYS_WAIT */
281 return NULL;
282 #endif
285 _IO_FILE *
286 _IO_new_popen (command, mode)
287 const char *command;
288 const char *mode;
290 struct locked_FILE
292 struct _IO_proc_file fpx;
293 #ifdef _IO_MTSAFE_IO
294 _IO_lock_t lock;
295 #endif
296 } *new_f;
297 _IO_FILE *fp;
299 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
300 if (new_f == NULL)
301 return NULL;
302 #ifdef _IO_MTSAFE_IO
303 new_f->fpx.file.file._lock = &new_f->lock;
304 #endif
305 fp = &new_f->fpx.file.file;
306 INTUSE(_IO_init) (fp, 0);
307 _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps;
308 _IO_new_file_init (&new_f->fpx.file);
309 #if !_IO_UNIFIED_JUMPTABLES
310 new_f->fpx.file.vtable = NULL;
311 #endif
312 if (_IO_new_proc_open (fp, command, mode) != NULL)
313 return (_IO_FILE *) &new_f->fpx.file;
314 INTUSE(_IO_un_link) (&new_f->fpx.file);
315 free (new_f);
316 return NULL;
320 _IO_new_proc_close (fp)
321 _IO_FILE *fp;
323 /* This is not name-space clean. FIXME! */
324 #if _IO_HAVE_SYS_WAIT
325 int wstatus;
326 _IO_proc_file **ptr = &proc_file_chain;
327 _IO_pid_t wait_pid;
328 int status = -1;
330 /* Unlink from proc_file_chain. */
331 #ifdef _IO_MTSAFE_IO
332 _IO_cleanup_region_start_noarg (unlock);
333 _IO_lock_lock (proc_file_chain_lock);
334 #endif
335 for ( ; *ptr != NULL; ptr = &(*ptr)->next)
337 if (*ptr == (_IO_proc_file *) fp)
339 *ptr = (*ptr)->next;
340 status = 0;
341 break;
344 #ifdef _IO_MTSAFE_IO
345 _IO_lock_unlock (proc_file_chain_lock);
346 _IO_cleanup_region_end (0);
347 #endif
349 if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
350 return -1;
351 /* POSIX.2 Rationale: "Some historical implementations either block
352 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
353 for the child process to terminate. Since this behavior is not
354 described in POSIX.2, such implementations are not conforming." */
357 wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
359 while (wait_pid == -1 && errno == EINTR);
360 if (wait_pid == -1)
361 return -1;
362 return wstatus;
363 #else /* !_IO_HAVE_SYS_WAIT */
364 return -1;
365 #endif
368 static const struct _IO_jump_t _IO_proc_jumps = {
369 JUMP_INIT_DUMMY,
370 JUMP_INIT(finish, _IO_new_file_finish),
371 JUMP_INIT(overflow, _IO_new_file_overflow),
372 JUMP_INIT(underflow, _IO_new_file_underflow),
373 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
374 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
375 JUMP_INIT(xsputn, _IO_new_file_xsputn),
376 JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
377 JUMP_INIT(seekoff, _IO_new_file_seekoff),
378 JUMP_INIT(seekpos, _IO_default_seekpos),
379 JUMP_INIT(setbuf, _IO_new_file_setbuf),
380 JUMP_INIT(sync, _IO_new_file_sync),
381 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
382 JUMP_INIT(read, INTUSE(_IO_file_read)),
383 JUMP_INIT(write, _IO_new_file_write),
384 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
385 JUMP_INIT(close, _IO_new_proc_close),
386 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
387 JUMP_INIT(showmanyc, _IO_default_showmanyc),
388 JUMP_INIT(imbue, _IO_default_imbue)
391 strong_alias (_IO_new_popen, __new_popen)
392 versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1);
393 versioned_symbol (libc, __new_popen, popen, GLIBC_2_1);
394 versioned_symbol (libc, _IO_new_proc_open, _IO_proc_open, GLIBC_2_1);
395 versioned_symbol (libc, _IO_new_proc_close, _IO_proc_close, GLIBC_2_1);