1 /* Copyright (C) 1993-2015 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
37 # include <shlib-compat.h>
38 # include <not-cancel.h>
40 #include <sys/types.h>
42 #include <kernel-features.h>
46 #define _IO_fork __fork
48 #define _IO_fork fork /* defined in libiberty, if needed */
50 extern _IO_pid_t
_IO_fork (void) __THROW
;
55 #define _IO_dup2 __dup2
59 extern int _IO_dup2 (int fd
, int fd2
) __THROW
;
64 #define _IO_waitpid waitpid_not_cancel
66 #define _IO_waitpid waitpid
71 #define _IO_execl execl
74 #define _IO__exit _exit
79 #define _IO_close close_not_cancel
81 #define _IO_close close
87 struct _IO_FILE_plus file
;
88 /* Following fields must match those in class procbuf (procbuf.h) */
90 struct _IO_proc_file
*next
;
92 typedef struct _IO_proc_file _IO_proc_file
;
94 static const struct _IO_jump_t _IO_proc_jumps
;
96 static struct _IO_proc_file
*proc_file_chain
;
99 static _IO_lock_t proc_file_chain_lock
= _IO_lock_initializer
;
102 unlock (void *not_used
)
104 _IO_lock_unlock (proc_file_chain_lock
);
109 _IO_new_proc_open (_IO_FILE
*fp
, const char *command
, const char *mode
)
112 int parent_end
, child_end
;
119 while (*mode
!= '\0')
133 __set_errno (EINVAL
);
137 if ((do_read
^ do_write
) == 0)
140 if (_IO_file_is_open (fp
))
144 # ifndef __ASSUME_PIPE2
145 if (__have_pipe2
>= 0)
148 int r
= __pipe2 (pipe_fds
, O_CLOEXEC
);
149 # ifndef __ASSUME_PIPE2
150 if (__have_pipe2
== 0)
151 __have_pipe2
= r
!= -1 || errno
!= ENOSYS
? 1 : -1;
153 if (__have_pipe2
> 0)
159 #ifndef __ASSUME_PIPE2
161 if (__have_pipe2
< 0)
163 if (__pipe (pipe_fds
) < 0)
169 parent_end
= pipe_fds
[0];
170 child_end
= pipe_fds
[1];
171 read_or_write
= _IO_NO_WRITES
;
175 parent_end
= pipe_fds
[1];
176 child_end
= pipe_fds
[0];
177 read_or_write
= _IO_NO_READS
;
180 ((_IO_proc_file
*) fp
)->pid
= child_pid
= _IO_fork ();
183 int child_std_end
= do_read
? 1 : 0;
184 struct _IO_proc_file
*p
;
186 #ifndef __ASSUME_PIPE2
187 /* If we have pipe2 the descriptor is marked for close-on-exec. */
188 _IO_close (parent_end
);
190 if (child_end
!= child_std_end
)
192 _IO_dup2 (child_end
, child_std_end
);
193 #ifndef __ASSUME_PIPE2
194 _IO_close (child_end
);
200 /* The descriptor is already the one we will use. But it must
201 not be marked close-on-exec. Undo the effects. */
202 # ifndef __ASSUME_PIPE2
203 if (__have_pipe2
> 0)
205 __fcntl (child_end
, F_SETFD
, 0);
208 /* POSIX.2: "popen() shall ensure that any streams from previous
209 popen() calls that remain open in the parent process are closed
210 in the new child process." */
211 for (p
= proc_file_chain
; p
; p
= p
->next
)
213 int fd
= _IO_fileno ((_IO_FILE
*) p
);
215 /* If any stream from previous popen() calls has fileno
216 child_std_end, it has been already closed by the dup2 syscall
218 if (fd
!= child_std_end
)
222 _IO_execl ("/bin/sh", "sh", "-c", command
, (char *) 0);
225 _IO_close (child_end
);
228 _IO_close (parent_end
);
234 #ifndef __ASSUME_PIPE2
236 if (__have_pipe2
< 0)
238 __fcntl (parent_end
, F_SETFD
, FD_CLOEXEC
);
244 /* Undo the effects of the pipe2 call which set the
245 close-on-exec flag. */
246 # ifndef __ASSUME_PIPE2
247 if (__have_pipe2
> 0)
249 __fcntl (parent_end
, F_SETFD
, 0);
253 _IO_fileno (fp
) = parent_end
;
255 /* Link into proc_file_chain. */
257 _IO_cleanup_region_start_noarg (unlock
);
258 _IO_lock_lock (proc_file_chain_lock
);
260 ((_IO_proc_file
*) fp
)->next
= proc_file_chain
;
261 proc_file_chain
= (_IO_proc_file
*) fp
;
263 _IO_lock_unlock (proc_file_chain_lock
);
264 _IO_cleanup_region_end (0);
267 _IO_mask_flags (fp
, read_or_write
, _IO_NO_READS
|_IO_NO_WRITES
);
272 _IO_new_popen (const char *command
, const char *mode
)
276 struct _IO_proc_file fpx
;
283 new_f
= (struct locked_FILE
*) malloc (sizeof (struct locked_FILE
));
287 new_f
->fpx
.file
.file
._lock
= &new_f
->lock
;
289 fp
= &new_f
->fpx
.file
.file
;
291 _IO_JUMPS (&new_f
->fpx
.file
) = &_IO_proc_jumps
;
292 _IO_new_file_init (&new_f
->fpx
.file
);
293 #if !_IO_UNIFIED_JUMPTABLES
294 new_f
->fpx
.file
.vtable
= NULL
;
296 if (_IO_new_proc_open (fp
, command
, mode
) != NULL
)
297 return (_IO_FILE
*) &new_f
->fpx
.file
;
298 _IO_un_link (&new_f
->fpx
.file
);
304 _IO_new_proc_close (_IO_FILE
*fp
)
306 /* This is not name-space clean. FIXME! */
308 _IO_proc_file
**ptr
= &proc_file_chain
;
312 /* Unlink from proc_file_chain. */
314 _IO_cleanup_region_start_noarg (unlock
);
315 _IO_lock_lock (proc_file_chain_lock
);
317 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
)
319 if (*ptr
== (_IO_proc_file
*) fp
)
327 _IO_lock_unlock (proc_file_chain_lock
);
328 _IO_cleanup_region_end (0);
331 if (status
< 0 || _IO_close (_IO_fileno(fp
)) < 0)
333 /* POSIX.2 Rationale: "Some historical implementations either block
334 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
335 for the child process to terminate. Since this behavior is not
336 described in POSIX.2, such implementations are not conforming." */
339 wait_pid
= _IO_waitpid (((_IO_proc_file
*) fp
)->pid
, &wstatus
, 0);
341 while (wait_pid
== -1 && errno
== EINTR
);
347 static const struct _IO_jump_t _IO_proc_jumps
= {
349 JUMP_INIT(finish
, _IO_new_file_finish
),
350 JUMP_INIT(overflow
, _IO_new_file_overflow
),
351 JUMP_INIT(underflow
, _IO_new_file_underflow
),
352 JUMP_INIT(uflow
, _IO_default_uflow
),
353 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
354 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
355 JUMP_INIT(xsgetn
, _IO_default_xsgetn
),
356 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
357 JUMP_INIT(seekpos
, _IO_default_seekpos
),
358 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
359 JUMP_INIT(sync
, _IO_new_file_sync
),
360 JUMP_INIT(doallocate
, _IO_file_doallocate
),
361 JUMP_INIT(read
, _IO_file_read
),
362 JUMP_INIT(write
, _IO_new_file_write
),
363 JUMP_INIT(seek
, _IO_file_seek
),
364 JUMP_INIT(close
, _IO_new_proc_close
),
365 JUMP_INIT(stat
, _IO_file_stat
),
366 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
367 JUMP_INIT(imbue
, _IO_default_imbue
)
370 strong_alias (_IO_new_popen
, __new_popen
)
371 versioned_symbol (libc
, _IO_new_popen
, _IO_popen
, GLIBC_2_1
);
372 versioned_symbol (libc
, __new_popen
, popen
, GLIBC_2_1
);
373 versioned_symbol (libc
, _IO_new_proc_open
, _IO_proc_open
, GLIBC_2_1
);
374 versioned_symbol (libc
, _IO_new_proc_close
, _IO_proc_close
, GLIBC_2_1
);