1 /* Copyright (C) 1998,99,2000 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 As a special exception, if you link the code in this file with
21 files compiled with a GNU compiler to produce an executable,
22 that does not cause the resulting executable to be covered by
23 the GNU Lesser General Public License. This exception does not
24 however invalidate any other reasons why the executable file
25 might be covered by the GNU Lesser General Public License.
26 This exception applies to code released by its copyright holders
27 in files containing the exception. */
29 #include <shlib-compat.h>
30 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
32 #define _IO_USE_OLD_IO_FILE
34 # define _POSIX_SOURCE
46 #include <sys/types.h>
51 #define _IO_fork __vfork
53 #define _IO_fork vfork /* defined in libiberty, if needed */
55 extern _IO_pid_t _IO_fork
__P ((void));
58 #endif /* _IO_HAVE_SYS_WAIT */
62 #define _IO_pipe __pipe
66 extern int _IO_pipe
__P ((int des
[2]));
71 #define _IO_dup2 __dup2
75 extern int _IO_dup2
__P ((int fd
, int fd2
));
80 #define _IO_waitpid __waitpid
82 #define _IO_waitpid waitpid
87 #define _IO_execl execl
90 #define _IO__exit _exit
95 #define _IO_close __close
97 #define _IO_close close
103 struct _IO_FILE_plus file
;
104 /* Following fields must match those in class procbuf (procbuf.h) */
106 struct _IO_proc_file
*next
;
108 typedef struct _IO_proc_file _IO_proc_file
;
110 static struct _IO_proc_file
*old_proc_file_chain
;
113 _IO_old_proc_open (fp
, command
, mode
)
118 #if _IO_HAVE_SYS_WAIT
119 volatile int read_or_write
;
120 volatile int parent_end
, child_end
;
123 if (_IO_file_is_open (fp
))
125 if (_IO_pipe (pipe_fds
) < 0)
127 if (mode
[0] == 'r' && mode
[1] == '\0')
129 parent_end
= pipe_fds
[0];
130 child_end
= pipe_fds
[1];
131 read_or_write
= _IO_NO_WRITES
;
133 else if (mode
[0] == 'w' && mode
[1] == '\0')
135 parent_end
= pipe_fds
[1];
136 child_end
= pipe_fds
[0];
137 read_or_write
= _IO_NO_READS
;
141 _IO_close (pipe_fds
[0]);
142 _IO_close (pipe_fds
[1]);
143 __set_errno (EINVAL
);
146 ((_IO_proc_file
*) fp
)->pid
= child_pid
= _IO_fork ();
149 int child_std_end
= mode
[0] == 'r' ? 1 : 0;
150 struct _IO_proc_file
*p
;
152 _IO_close (parent_end
);
153 if (child_end
!= child_std_end
)
155 _IO_dup2 (child_end
, child_std_end
);
156 _IO_close (child_end
);
158 /* POSIX.2: "popen() shall ensure that any streams from previous
159 popen() calls that remain open in the parent process are closed
160 in the new child process." */
161 for (p
= old_proc_file_chain
; p
; p
= p
->next
)
162 _IO_close (_IO_fileno ((_IO_FILE
*) p
));
164 _IO_execl ("/bin/sh", "sh", "-c", command
, (char *) 0);
167 _IO_close (child_end
);
170 _IO_close (parent_end
);
173 _IO_fileno (fp
) = parent_end
;
175 /* Link into old_proc_file_chain. */
176 ((_IO_proc_file
*) fp
)->next
= old_proc_file_chain
;
177 old_proc_file_chain
= (_IO_proc_file
*) fp
;
179 _IO_mask_flags (fp
, read_or_write
, _IO_NO_READS
|_IO_NO_WRITES
);
181 #else /* !_IO_HAVE_SYS_WAIT */
187 _IO_old_popen (command
, mode
)
193 struct _IO_proc_file fpx
;
200 new_f
= (struct locked_FILE
*) malloc (sizeof (struct locked_FILE
));
204 new_f
->fpx
.file
.file
._lock
= &new_f
->lock
;
206 fp
= &new_f
->fpx
.file
.file
;
208 _IO_JUMPS (&new_f
->fpx
.file
) = &_IO_old_proc_jumps
;
209 _IO_old_file_init (&new_f
->fpx
.file
);
210 #if !_IO_UNIFIED_JUMPTABLES
211 new_f
->fpx
.file
.vtable
= NULL
;
213 if (_IO_old_proc_open (fp
, command
, mode
) != NULL
)
215 _IO_un_link (&new_f
->fpx
.file
);
221 _IO_old_proc_close (fp
)
224 /* This is not name-space clean. FIXME! */
225 #if _IO_HAVE_SYS_WAIT
227 _IO_proc_file
**ptr
= &old_proc_file_chain
;
231 /* Unlink from old_proc_file_chain. */
232 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
)
234 if (*ptr
== (_IO_proc_file
*) fp
)
242 if (status
< 0 || _IO_close (_IO_fileno(fp
)) < 0)
244 /* POSIX.2 Rationale: "Some historical implementations either block
245 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
246 for the child process to terminate. Since this behavior is not
247 described in POSIX.2, such implementations are not conforming." */
250 wait_pid
= _IO_waitpid (((_IO_proc_file
*) fp
)->pid
, &wstatus
, 0);
252 while (wait_pid
== -1 && errno
== EINTR
);
256 #else /* !_IO_HAVE_SYS_WAIT */
261 struct _IO_jump_t _IO_old_proc_jumps
= {
263 JUMP_INIT(finish
, _IO_old_file_finish
),
264 JUMP_INIT(overflow
, _IO_old_file_overflow
),
265 JUMP_INIT(underflow
, _IO_old_file_underflow
),
266 JUMP_INIT(uflow
, _IO_default_uflow
),
267 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
268 JUMP_INIT(xsputn
, _IO_old_file_xsputn
),
269 JUMP_INIT(xsgetn
, _IO_default_xsgetn
),
270 JUMP_INIT(seekoff
, _IO_old_file_seekoff
),
271 JUMP_INIT(seekpos
, _IO_default_seekpos
),
272 JUMP_INIT(setbuf
, _IO_old_file_setbuf
),
273 JUMP_INIT(sync
, _IO_old_file_sync
),
274 JUMP_INIT(doallocate
, _IO_file_doallocate
),
275 JUMP_INIT(read
, _IO_file_read
),
276 JUMP_INIT(write
, _IO_old_file_write
),
277 JUMP_INIT(seek
, _IO_file_seek
),
278 JUMP_INIT(close
, _IO_old_proc_close
),
279 JUMP_INIT(stat
, _IO_file_stat
),
280 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
281 JUMP_INIT(imbue
, _IO_default_imbue
)
284 strong_alias (_IO_old_popen
, __old_popen
)
285 compat_symbol (libc
, _IO_old_popen
, _IO_popen
, GLIBC_2_0
);
286 compat_symbol (libc
, __old_popen
, popen
, GLIBC_2_0
);
287 compat_symbol (libc
, _IO_old_proc_open
, _IO_proc_open
, GLIBC_2_0
);
288 compat_symbol (libc
, _IO_old_proc_close
, _IO_proc_close
, GLIBC_2_0
);