]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/oldiopopen.c
Bug 24535: Update to Unicode 12.1.0
[thirdparty/glibc.git] / libio / oldiopopen.c
CommitLineData
04277e02 1/* Copyright (C) 1998-2019 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
7d6a8338
UD
3 Written by Per Bothner <bothner@cygnus.com>.
4
41bdb6e2
AJ
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.
7d6a8338 9
41bdb6e2
AJ
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
7d6a8338 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
7d6a8338 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>.
7d6a8338 18
41bdb6e2
AJ
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. */
7d6a8338
UD
27
28#define _IO_USE_OLD_IO_FILE
7d6a8338 29#include "libioP.h"
7d6a8338
UD
30#include <signal.h>
31#include <unistd.h>
7d6a8338 32#include <stdlib.h>
5f0704b6 33#include <unistd.h>
7d6a8338
UD
34#include <sys/types.h>
35#include <sys/wait.h>
36
5656e294
RM
37#include <shlib-compat.h>
38#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
39
7d6a8338
UD
40struct _IO_proc_file
41{
7ea11363 42 struct _IO_FILE_complete_plus file;
7d6a8338 43 /* Following fields must match those in class procbuf (procbuf.h) */
9964a145 44 pid_t pid;
7d6a8338
UD
45 struct _IO_proc_file *next;
46};
47typedef struct _IO_proc_file _IO_proc_file;
48
390500b1 49static struct _IO_proc_file *old_proc_file_chain;
7d6a8338 50
ad71126b
UD
51#ifdef _IO_MTSAFE_IO
52static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer;
53
54static void
55unlock (void *not_used)
56{
57 _IO_lock_unlock (proc_file_chain_lock);
58}
59#endif
60
9964a145 61FILE *
4a381a81 62attribute_compat_text_section
9964a145 63_IO_old_proc_open (FILE *fp, const char *command, const char *mode)
7d6a8338 64{
7d6a8338
UD
65 volatile int read_or_write;
66 volatile int parent_end, child_end;
67 int pipe_fds[2];
9964a145 68 pid_t child_pid;
7d6a8338
UD
69 if (_IO_file_is_open (fp))
70 return NULL;
5f0704b6 71 if (__pipe (pipe_fds) < 0)
7d6a8338
UD
72 return NULL;
73 if (mode[0] == 'r' && mode[1] == '\0')
74 {
75 parent_end = pipe_fds[0];
76 child_end = pipe_fds[1];
77 read_or_write = _IO_NO_WRITES;
78 }
79 else if (mode[0] == 'w' && mode[1] == '\0')
80 {
81 parent_end = pipe_fds[1];
82 child_end = pipe_fds[0];
83 read_or_write = _IO_NO_READS;
84 }
85 else
86 {
5f0704b6
FW
87 __close (pipe_fds[0]);
88 __close (pipe_fds[1]);
7d6a8338
UD
89 __set_errno (EINVAL);
90 return NULL;
91 }
5f0704b6 92 ((_IO_proc_file *) fp)->pid = child_pid = __fork ();
7d6a8338
UD
93 if (child_pid == 0)
94 {
95 int child_std_end = mode[0] == 'r' ? 1 : 0;
655c0697 96 struct _IO_proc_file *p;
16710d58 97
5f0704b6 98 __close (parent_end);
7d6a8338
UD
99 if (child_end != child_std_end)
100 {
5f0704b6
FW
101 __dup2 (child_end, child_std_end);
102 __close (child_end);
7d6a8338
UD
103 }
104 /* POSIX.2: "popen() shall ensure that any streams from previous
105 popen() calls that remain open in the parent process are closed
106 in the new child process." */
655c0697 107 for (p = old_proc_file_chain; p; p = p->next)
9964a145 108 __close (_IO_fileno ((FILE *) p));
7d6a8338 109
5f0704b6
FW
110 execl ("/bin/sh", "sh", "-c", command, (char *) 0);
111 _exit (127);
7d6a8338 112 }
5f0704b6 113 __close (child_end);
7d6a8338
UD
114 if (child_pid < 0)
115 {
5f0704b6 116 __close (parent_end);
7d6a8338
UD
117 return NULL;
118 }
119 _IO_fileno (fp) = parent_end;
120
121 /* Link into old_proc_file_chain. */
9ec9864b 122#ifdef _IO_MTSAFE_IO
ad71126b
UD
123 _IO_cleanup_region_start_noarg (unlock);
124 _IO_lock_lock (proc_file_chain_lock);
125#endif
7d6a8338
UD
126 ((_IO_proc_file *) fp)->next = old_proc_file_chain;
127 old_proc_file_chain = (_IO_proc_file *) fp;
9ec9864b 128#ifdef _IO_MTSAFE_IO
ad71126b
UD
129 _IO_lock_unlock (proc_file_chain_lock);
130 _IO_cleanup_region_end (0);
131#endif
7d6a8338
UD
132
133 _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
134 return fp;
7d6a8338
UD
135}
136
9964a145 137FILE *
4a381a81 138attribute_compat_text_section
9d46370c 139_IO_old_popen (const char *command, const char *mode)
7d6a8338
UD
140{
141 struct locked_FILE
142 {
143 struct _IO_proc_file fpx;
144#ifdef _IO_MTSAFE_IO
145 _IO_lock_t lock;
146#endif
147 } *new_f;
9964a145 148 FILE *fp;
7d6a8338
UD
149
150 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
151 if (new_f == NULL)
152 return NULL;
153#ifdef _IO_MTSAFE_IO
7ea11363 154 new_f->fpx.file.file._file._lock = &new_f->lock;
7d6a8338 155#endif
7ea11363
UD
156 fp = &new_f->fpx.file.file._file;
157 _IO_old_init (fp, 0);
e69dcccb 158 _IO_JUMPS_FILE_plus (&new_f->fpx.file) = &_IO_old_proc_jumps;
db3476af 159 _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fpx.file);
7d6a8338
UD
160 if (_IO_old_proc_open (fp, command, mode) != NULL)
161 return fp;
d18ea0c5 162 _IO_un_link ((struct _IO_FILE_plus *) &new_f->fpx.file);
7d6a8338
UD
163 free (new_f);
164 return NULL;
165}
166
167int
4a381a81 168attribute_compat_text_section
9964a145 169_IO_old_proc_close (FILE *fp)
7d6a8338
UD
170{
171 /* This is not name-space clean. FIXME! */
7d6a8338
UD
172 int wstatus;
173 _IO_proc_file **ptr = &old_proc_file_chain;
9964a145 174 pid_t wait_pid;
7d6a8338
UD
175 int status = -1;
176
177 /* Unlink from old_proc_file_chain. */
9ec9864b 178#ifdef _IO_MTSAFE_IO
ad71126b
UD
179 _IO_cleanup_region_start_noarg (unlock);
180 _IO_lock_lock (proc_file_chain_lock);
181#endif
7d6a8338
UD
182 for ( ; *ptr != NULL; ptr = &(*ptr)->next)
183 {
184 if (*ptr == (_IO_proc_file *) fp)
185 {
186 *ptr = (*ptr)->next;
187 status = 0;
188 break;
189 }
190 }
9ec9864b 191#ifdef _IO_MTSAFE_IO
ad71126b
UD
192 _IO_lock_unlock (proc_file_chain_lock);
193 _IO_cleanup_region_end (0);
194#endif
7d6a8338 195
5f0704b6 196 if (status < 0 || __close (_IO_fileno(fp)) < 0)
7d6a8338
UD
197 return -1;
198 /* POSIX.2 Rationale: "Some historical implementations either block
199 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
200 for the child process to terminate. Since this behavior is not
201 described in POSIX.2, such implementations are not conforming." */
202 do
203 {
5f0704b6 204 wait_pid = __waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
7d6a8338
UD
205 }
206 while (wait_pid == -1 && errno == EINTR);
207 if (wait_pid == -1)
208 return -1;
209 return wstatus;
7d6a8338
UD
210}
211
db3476af 212const struct _IO_jump_t _IO_old_proc_jumps libio_vtable = {
7d6a8338
UD
213 JUMP_INIT_DUMMY,
214 JUMP_INIT(finish, _IO_old_file_finish),
215 JUMP_INIT(overflow, _IO_old_file_overflow),
216 JUMP_INIT(underflow, _IO_old_file_underflow),
d18ea0c5
AS
217 JUMP_INIT(uflow, _IO_default_uflow),
218 JUMP_INIT(pbackfail, _IO_default_pbackfail),
7d6a8338 219 JUMP_INIT(xsputn, _IO_old_file_xsputn),
d18ea0c5 220 JUMP_INIT(xsgetn, _IO_default_xsgetn),
7d6a8338
UD
221 JUMP_INIT(seekoff, _IO_old_file_seekoff),
222 JUMP_INIT(seekpos, _IO_default_seekpos),
223 JUMP_INIT(setbuf, _IO_old_file_setbuf),
224 JUMP_INIT(sync, _IO_old_file_sync),
d18ea0c5
AS
225 JUMP_INIT(doallocate, _IO_file_doallocate),
226 JUMP_INIT(read, _IO_file_read),
7d6a8338 227 JUMP_INIT(write, _IO_old_file_write),
d18ea0c5 228 JUMP_INIT(seek, _IO_file_seek),
7d6a8338 229 JUMP_INIT(close, _IO_old_proc_close),
d18ea0c5 230 JUMP_INIT(stat, _IO_file_stat),
7d6a8338
UD
231 JUMP_INIT(showmanyc, _IO_default_showmanyc),
232 JUMP_INIT(imbue, _IO_default_imbue)
233};
234
235strong_alias (_IO_old_popen, __old_popen)
16710d58
RM
236compat_symbol (libc, _IO_old_popen, _IO_popen, GLIBC_2_0);
237compat_symbol (libc, __old_popen, popen, GLIBC_2_0);
238compat_symbol (libc, _IO_old_proc_open, _IO_proc_open, GLIBC_2_0);
239compat_symbol (libc, _IO_old_proc_close, _IO_proc_close, GLIBC_2_0);
240
241#endif