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. */
29 # define _POSIX_SOURCE
38 # include <shlib-compat.h>
39 # include <not-cancel.h>
41 #include <sys/types.h>
43 #include <kernel-features.h>
47 #define _IO_fork __fork
49 #define _IO_fork fork /* defined in libiberty, if needed */
51 extern _IO_pid_t
_IO_fork (void) __THROW
;
54 #endif /* _IO_HAVE_SYS_WAIT */
58 #define _IO_dup2 __dup2
62 extern int _IO_dup2 (int fd
, int fd2
) __THROW
;
67 #define _IO_waitpid waitpid_not_cancel
69 #define _IO_waitpid waitpid
74 #define _IO_execl execl
77 #define _IO__exit _exit
82 #define _IO_close close_not_cancel
84 #define _IO_close close
90 struct _IO_FILE_plus file
;
91 /* Following fields must match those in class procbuf (procbuf.h) */
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
;
102 static _IO_lock_t proc_file_chain_lock
= _IO_lock_initializer
;
105 unlock (void *not_used
)
107 _IO_lock_unlock (proc_file_chain_lock
);
112 _IO_new_proc_open (fp
, command
, mode
)
117 #if _IO_HAVE_SYS_WAIT
119 int parent_end
, child_end
;
126 while (*mode
!= '\0')
140 __set_errno (EINVAL
);
144 if ((do_read
^ do_write
) == 0)
147 if (_IO_file_is_open (fp
))
151 # ifndef __ASSUME_PIPE2
152 if (__have_pipe2
>= 0)
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)
166 #ifndef __ASSUME_PIPE2
168 if (__have_pipe2
< 0)
170 if (__pipe (pipe_fds
) < 0)
176 parent_end
= pipe_fds
[0];
177 child_end
= pipe_fds
[1];
178 read_or_write
= _IO_NO_WRITES
;
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 ();
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
);
197 if (child_end
!= child_std_end
)
199 _IO_dup2 (child_end
, child_std_end
);
200 #ifndef __ASSUME_PIPE2
201 _IO_close (child_end
);
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)
212 __fcntl (child_end
, F_SETFD
, 0);
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
225 if (fd
!= child_std_end
)
229 _IO_execl ("/bin/sh", "sh", "-c", command
, (char *) 0);
232 _IO_close (child_end
);
235 _IO_close (parent_end
);
241 #ifndef __ASSUME_PIPE2
243 if (__have_pipe2
< 0)
245 __fcntl (parent_end
, F_SETFD
, FD_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)
256 __fcntl (parent_end
, F_SETFD
, 0);
260 _IO_fileno (fp
) = parent_end
;
262 /* Link into proc_file_chain. */
264 _IO_cleanup_region_start_noarg (unlock
);
265 _IO_lock_lock (proc_file_chain_lock
);
267 ((_IO_proc_file
*) fp
)->next
= proc_file_chain
;
268 proc_file_chain
= (_IO_proc_file
*) fp
;
270 _IO_lock_unlock (proc_file_chain_lock
);
271 _IO_cleanup_region_end (0);
274 _IO_mask_flags (fp
, read_or_write
, _IO_NO_READS
|_IO_NO_WRITES
);
276 #else /* !_IO_HAVE_SYS_WAIT */
282 _IO_new_popen (command
, mode
)
288 struct _IO_proc_file fpx
;
295 new_f
= (struct locked_FILE
*) malloc (sizeof (struct locked_FILE
));
299 new_f
->fpx
.file
.file
._lock
= &new_f
->lock
;
301 fp
= &new_f
->fpx
.file
.file
;
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
;
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
);
316 _IO_new_proc_close (fp
)
319 /* This is not name-space clean. FIXME! */
320 #if _IO_HAVE_SYS_WAIT
322 _IO_proc_file
**ptr
= &proc_file_chain
;
326 /* Unlink from proc_file_chain. */
328 _IO_cleanup_region_start_noarg (unlock
);
329 _IO_lock_lock (proc_file_chain_lock
);
331 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
)
333 if (*ptr
== (_IO_proc_file
*) fp
)
341 _IO_lock_unlock (proc_file_chain_lock
);
342 _IO_cleanup_region_end (0);
345 if (status
< 0 || _IO_close (_IO_fileno(fp
)) < 0)
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
);
359 #else /* !_IO_HAVE_SYS_WAIT */
364 static const struct _IO_jump_t _IO_proc_jumps
= {
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
);