arm: fix up style in reloc fix
[glibc.git] / libio / iopopen.c
blob4f67e8ccad4009899c949fb15d730f818e318a64
1 /* Copyright (C) 1993-2012 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Per Bothner <bothner@cygnus.com>.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>.
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
28 #ifndef _POSIX_SOURCE
29 # define _POSIX_SOURCE
30 #endif
31 #include "libioP.h"
32 #if _IO_HAVE_SYS_WAIT
33 #include <signal.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #ifdef _LIBC
37 # include <unistd.h>
38 # include <shlib-compat.h>
39 # include <not-cancel.h>
40 #endif
41 #include <sys/types.h>
42 #include <sys/wait.h>
43 #include <kernel-features.h>
45 #ifndef _IO_fork
46 #ifdef _LIBC
47 #define _IO_fork __fork
48 #else
49 #define _IO_fork fork /* defined in libiberty, if needed */
50 #endif
51 extern _IO_pid_t _IO_fork (void) __THROW;
52 #endif
54 #endif /* _IO_HAVE_SYS_WAIT */
56 #ifndef _IO_dup2
57 #ifdef _LIBC
58 #define _IO_dup2 __dup2
59 #else
60 #define _IO_dup2 dup2
61 #endif
62 extern int _IO_dup2 (int fd, int fd2) __THROW;
63 #endif
65 #ifndef _IO_waitpid
66 #ifdef _LIBC
67 #define _IO_waitpid waitpid_not_cancel
68 #else
69 #define _IO_waitpid waitpid
70 #endif
71 #endif
73 #ifndef _IO_execl
74 #define _IO_execl execl
75 #endif
76 #ifndef _IO__exit
77 #define _IO__exit _exit
78 #endif
80 #ifndef _IO_close
81 #ifdef _LIBC
82 #define _IO_close close_not_cancel
83 #else
84 #define _IO_close close
85 #endif
86 #endif
88 struct _IO_proc_file
90 struct _IO_FILE_plus file;
91 /* Following fields must match those in class procbuf (procbuf.h) */
92 _IO_pid_t pid;
93 struct _IO_proc_file *next;
95 typedef struct _IO_proc_file _IO_proc_file;
97 static const struct _IO_jump_t _IO_proc_jumps;
99 static struct _IO_proc_file *proc_file_chain;
101 #ifdef _IO_MTSAFE_IO
102 static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer;
104 static void
105 unlock (void *not_used)
107 _IO_lock_unlock (proc_file_chain_lock);
109 #endif
111 _IO_FILE *
112 _IO_new_proc_open (fp, command, mode)
113 _IO_FILE *fp;
114 const char *command;
115 const char *mode;
117 #if _IO_HAVE_SYS_WAIT
118 int read_or_write;
119 int parent_end, child_end;
120 int pipe_fds[2];
121 _IO_pid_t child_pid;
123 int do_read = 0;
124 int do_write = 0;
125 int do_cloexec = 0;
126 while (*mode != '\0')
127 switch (*mode++)
129 case 'r':
130 do_read = 1;
131 break;
132 case 'w':
133 do_write = 1;
134 break;
135 case 'e':
136 do_cloexec = 1;
137 break;
138 default:
139 errout:
140 __set_errno (EINVAL);
141 return NULL;
144 if ((do_read ^ do_write) == 0)
145 goto errout;
147 if (_IO_file_is_open (fp))
148 return NULL;
150 #ifdef O_CLOEXEC
151 # ifndef __ASSUME_PIPE2
152 if (__have_pipe2 >= 0)
153 # endif
155 int r = __pipe2 (pipe_fds, O_CLOEXEC);
156 # ifndef __ASSUME_PIPE2
157 if (__have_pipe2 == 0)
158 __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1;
160 if (__have_pipe2 > 0)
161 # endif
162 if (r < 0)
163 return NULL;
165 #endif
166 #ifndef __ASSUME_PIPE2
167 # ifdef O_CLOEXEC
168 if (__have_pipe2 < 0)
169 # endif
170 if (__pipe (pipe_fds) < 0)
171 return NULL;
172 #endif
174 if (do_read)
176 parent_end = pipe_fds[0];
177 child_end = pipe_fds[1];
178 read_or_write = _IO_NO_WRITES;
180 else
182 parent_end = pipe_fds[1];
183 child_end = pipe_fds[0];
184 read_or_write = _IO_NO_READS;
187 ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
188 if (child_pid == 0)
190 int child_std_end = do_read ? 1 : 0;
191 struct _IO_proc_file *p;
193 #ifndef __ASSUME_PIPE2
194 /* If we have pipe2 the descriptor is marked for close-on-exec. */
195 _IO_close (parent_end);
196 #endif
197 if (child_end != child_std_end)
199 _IO_dup2 (child_end, child_std_end);
200 #ifndef __ASSUME_PIPE2
201 _IO_close (child_end);
202 #endif
204 #ifdef O_CLOEXEC
205 else
207 /* The descriptor is already the one we will use. But it must
208 not be marked close-on-exec. Undo the effects. */
209 # ifndef __ASSUME_PIPE2
210 if (__have_pipe2 > 0)
211 # endif
212 __fcntl (child_end, F_SETFD, 0);
214 #endif
215 /* POSIX.2: "popen() shall ensure that any streams from previous
216 popen() calls that remain open in the parent process are closed
217 in the new child process." */
218 for (p = proc_file_chain; p; p = p->next)
220 int fd = _IO_fileno ((_IO_FILE *) p);
222 /* If any stream from previous popen() calls has fileno
223 child_std_end, it has been already closed by the dup2 syscall
224 above. */
225 if (fd != child_std_end)
226 _IO_close (fd);
229 _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
230 _IO__exit (127);
232 _IO_close (child_end);
233 if (child_pid < 0)
235 _IO_close (parent_end);
236 return NULL;
239 if (do_cloexec)
241 #ifndef __ASSUME_PIPE2
242 # ifdef O_CLOEXEC
243 if (__have_pipe2 < 0)
244 # endif
245 __fcntl (parent_end, F_SETFD, FD_CLOEXEC);
246 #endif
248 else
250 #ifdef O_CLOEXEC
251 /* Undo the effects of the pipe2 call which set the
252 close-on-exec flag. */
253 # ifndef __ASSUME_PIPE2
254 if (__have_pipe2 > 0)
255 # endif
256 __fcntl (parent_end, F_SETFD, 0);
257 #endif
260 _IO_fileno (fp) = parent_end;
262 /* Link into proc_file_chain. */
263 #ifdef _IO_MTSAFE_IO
264 _IO_cleanup_region_start_noarg (unlock);
265 _IO_lock_lock (proc_file_chain_lock);
266 #endif
267 ((_IO_proc_file *) fp)->next = proc_file_chain;
268 proc_file_chain = (_IO_proc_file *) fp;
269 #ifdef _IO_MTSAFE_IO
270 _IO_lock_unlock (proc_file_chain_lock);
271 _IO_cleanup_region_end (0);
272 #endif
274 _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
275 return fp;
276 #else /* !_IO_HAVE_SYS_WAIT */
277 return NULL;
278 #endif
281 _IO_FILE *
282 _IO_new_popen (command, mode)
283 const char *command;
284 const char *mode;
286 struct locked_FILE
288 struct _IO_proc_file fpx;
289 #ifdef _IO_MTSAFE_IO
290 _IO_lock_t lock;
291 #endif
292 } *new_f;
293 _IO_FILE *fp;
295 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
296 if (new_f == NULL)
297 return NULL;
298 #ifdef _IO_MTSAFE_IO
299 new_f->fpx.file.file._lock = &new_f->lock;
300 #endif
301 fp = &new_f->fpx.file.file;
302 _IO_init (fp, 0);
303 _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps;
304 _IO_new_file_init (&new_f->fpx.file);
305 #if !_IO_UNIFIED_JUMPTABLES
306 new_f->fpx.file.vtable = NULL;
307 #endif
308 if (_IO_new_proc_open (fp, command, mode) != NULL)
309 return (_IO_FILE *) &new_f->fpx.file;
310 _IO_un_link (&new_f->fpx.file);
311 free (new_f);
312 return NULL;
316 _IO_new_proc_close (fp)
317 _IO_FILE *fp;
319 /* This is not name-space clean. FIXME! */
320 #if _IO_HAVE_SYS_WAIT
321 int wstatus;
322 _IO_proc_file **ptr = &proc_file_chain;
323 _IO_pid_t wait_pid;
324 int status = -1;
326 /* Unlink from proc_file_chain. */
327 #ifdef _IO_MTSAFE_IO
328 _IO_cleanup_region_start_noarg (unlock);
329 _IO_lock_lock (proc_file_chain_lock);
330 #endif
331 for ( ; *ptr != NULL; ptr = &(*ptr)->next)
333 if (*ptr == (_IO_proc_file *) fp)
335 *ptr = (*ptr)->next;
336 status = 0;
337 break;
340 #ifdef _IO_MTSAFE_IO
341 _IO_lock_unlock (proc_file_chain_lock);
342 _IO_cleanup_region_end (0);
343 #endif
345 if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
346 return -1;
347 /* POSIX.2 Rationale: "Some historical implementations either block
348 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
349 for the child process to terminate. Since this behavior is not
350 described in POSIX.2, such implementations are not conforming." */
353 wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
355 while (wait_pid == -1 && errno == EINTR);
356 if (wait_pid == -1)
357 return -1;
358 return wstatus;
359 #else /* !_IO_HAVE_SYS_WAIT */
360 return -1;
361 #endif
364 static const struct _IO_jump_t _IO_proc_jumps = {
365 JUMP_INIT_DUMMY,
366 JUMP_INIT(finish, _IO_new_file_finish),
367 JUMP_INIT(overflow, _IO_new_file_overflow),
368 JUMP_INIT(underflow, _IO_new_file_underflow),
369 JUMP_INIT(uflow, _IO_default_uflow),
370 JUMP_INIT(pbackfail, _IO_default_pbackfail),
371 JUMP_INIT(xsputn, _IO_new_file_xsputn),
372 JUMP_INIT(xsgetn, _IO_default_xsgetn),
373 JUMP_INIT(seekoff, _IO_new_file_seekoff),
374 JUMP_INIT(seekpos, _IO_default_seekpos),
375 JUMP_INIT(setbuf, _IO_new_file_setbuf),
376 JUMP_INIT(sync, _IO_new_file_sync),
377 JUMP_INIT(doallocate, _IO_file_doallocate),
378 JUMP_INIT(read, _IO_file_read),
379 JUMP_INIT(write, _IO_new_file_write),
380 JUMP_INIT(seek, _IO_file_seek),
381 JUMP_INIT(close, _IO_new_proc_close),
382 JUMP_INIT(stat, _IO_file_stat),
383 JUMP_INIT(showmanyc, _IO_default_showmanyc),
384 JUMP_INIT(imbue, _IO_default_imbue)
387 strong_alias (_IO_new_popen, __new_popen)
388 versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1);
389 versioned_symbol (libc, __new_popen, popen, GLIBC_2_1);
390 versioned_symbol (libc, _IO_new_proc_open, _IO_proc_open, GLIBC_2_1);
391 versioned_symbol (libc, _IO_new_proc_close, _IO_proc_close, GLIBC_2_1);