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
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. */
31 # define _POSIX_SOURCE
42 # include <shlib-compat.h>
43 # include <not-cancel.h>
45 #include <sys/types.h>
47 #include <kernel-features.h>
51 #define _IO_fork __fork
53 #define _IO_fork fork /* defined in libiberty, if needed */
55 extern _IO_pid_t
_IO_fork (void) __THROW
;
58 #endif /* _IO_HAVE_SYS_WAIT */
62 #define _IO_dup2 __dup2
66 extern int _IO_dup2 (int fd
, int fd2
) __THROW
;
71 #define _IO_waitpid waitpid_not_cancel
73 #define _IO_waitpid waitpid
78 #define _IO_execl execl
81 #define _IO__exit _exit
86 #define _IO_close close_not_cancel
88 #define _IO_close close
94 struct _IO_FILE_plus file
;
95 /* Following fields must match those in class procbuf (procbuf.h) */
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
;
106 static _IO_lock_t proc_file_chain_lock
= _IO_lock_initializer
;
109 unlock (void *not_used
)
111 _IO_lock_unlock (proc_file_chain_lock
);
116 _IO_new_proc_open (fp
, command
, mode
)
121 #if _IO_HAVE_SYS_WAIT
123 int parent_end
, child_end
;
130 while (*mode
!= '\0')
144 __set_errno (EINVAL
);
148 if ((do_read
^ do_write
) == 0)
151 if (_IO_file_is_open (fp
))
155 # ifndef __ASSUME_PIPE2
156 if (__have_pipe2
>= 0)
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)
170 #ifndef __ASSUME_PIPE2
172 if (__have_pipe2
< 0)
174 if (__pipe (pipe_fds
) < 0)
180 parent_end
= pipe_fds
[0];
181 child_end
= pipe_fds
[1];
182 read_or_write
= _IO_NO_WRITES
;
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 ();
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
);
201 if (child_end
!= child_std_end
)
203 _IO_dup2 (child_end
, child_std_end
);
204 #ifndef __ASSUME_PIPE2
205 _IO_close (child_end
);
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)
216 __fcntl (child_end
, F_SETFD
, 0);
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
229 if (fd
!= child_std_end
)
233 _IO_execl ("/bin/sh", "sh", "-c", command
, (char *) 0);
236 _IO_close (child_end
);
239 _IO_close (parent_end
);
245 #ifndef __ASSUME_PIPE2
247 if (__have_pipe2
< 0)
249 __fcntl (parent_end
, F_SETFD
, FD_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)
260 __fcntl (parent_end
, F_SETFD
, 0);
264 _IO_fileno (fp
) = parent_end
;
266 /* Link into proc_file_chain. */
268 _IO_cleanup_region_start_noarg (unlock
);
269 _IO_lock_lock (proc_file_chain_lock
);
271 ((_IO_proc_file
*) fp
)->next
= proc_file_chain
;
272 proc_file_chain
= (_IO_proc_file
*) fp
;
274 _IO_lock_unlock (proc_file_chain_lock
);
275 _IO_cleanup_region_end (0);
278 _IO_mask_flags (fp
, read_or_write
, _IO_NO_READS
|_IO_NO_WRITES
);
280 #else /* !_IO_HAVE_SYS_WAIT */
286 _IO_new_popen (command
, mode
)
292 struct _IO_proc_file fpx
;
299 new_f
= (struct locked_FILE
*) malloc (sizeof (struct locked_FILE
));
303 new_f
->fpx
.file
.file
._lock
= &new_f
->lock
;
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
;
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
);
320 _IO_new_proc_close (fp
)
323 /* This is not name-space clean. FIXME! */
324 #if _IO_HAVE_SYS_WAIT
326 _IO_proc_file
**ptr
= &proc_file_chain
;
330 /* Unlink from proc_file_chain. */
332 _IO_cleanup_region_start_noarg (unlock
);
333 _IO_lock_lock (proc_file_chain_lock
);
335 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
)
337 if (*ptr
== (_IO_proc_file
*) fp
)
345 _IO_lock_unlock (proc_file_chain_lock
);
346 _IO_cleanup_region_end (0);
349 if (status
< 0 || _IO_close (_IO_fileno(fp
)) < 0)
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
);
363 #else /* !_IO_HAVE_SYS_WAIT */
368 static const struct _IO_jump_t _IO_proc_jumps
= {
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
);