UnicodeData has precedence over EastAsianWidth
[glibc.git] / libio / iopopen.c
blobb78e7e5ef265c2a025f5bd2a1b4e57290a7e90ed
1 /* Copyright (C) 1993-2017 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. */
28 #ifndef _POSIX_SOURCE
29 # define _POSIX_SOURCE
30 #endif
31 #include "libioP.h"
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #ifdef _LIBC
37 # include <shlib-compat.h>
38 # include <not-cancel.h>
39 #endif
40 #include <sys/types.h>
41 #include <sys/wait.h>
42 #include <kernel-features.h>
44 #ifndef _IO_fork
45 #ifdef _LIBC
46 #define _IO_fork __fork
47 #else
48 #define _IO_fork fork /* defined in libiberty, if needed */
49 #endif
50 extern _IO_pid_t _IO_fork (void) __THROW;
51 #endif
53 #ifndef _IO_dup2
54 #ifdef _LIBC
55 #define _IO_dup2 __dup2
56 #else
57 #define _IO_dup2 dup2
58 #endif
59 extern int _IO_dup2 (int fd, int fd2) __THROW;
60 #endif
62 #ifndef _IO_waitpid
63 #ifdef _LIBC
64 #define _IO_waitpid waitpid_not_cancel
65 #else
66 #define _IO_waitpid waitpid
67 #endif
68 #endif
70 #ifndef _IO_execl
71 #define _IO_execl execl
72 #endif
73 #ifndef _IO__exit
74 #define _IO__exit _exit
75 #endif
77 #ifndef _IO_close
78 #ifdef _LIBC
79 #define _IO_close close_not_cancel
80 #else
81 #define _IO_close close
82 #endif
83 #endif
85 struct _IO_proc_file
87 struct _IO_FILE_plus file;
88 /* Following fields must match those in class procbuf (procbuf.h) */
89 _IO_pid_t pid;
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;
98 #ifdef _IO_MTSAFE_IO
99 static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer;
101 static void
102 unlock (void *not_used)
104 _IO_lock_unlock (proc_file_chain_lock);
106 #endif
108 _IO_FILE *
109 _IO_new_proc_open (_IO_FILE *fp, const char *command, const char *mode)
111 int read_or_write;
112 int parent_end, child_end;
113 int pipe_fds[2];
114 _IO_pid_t child_pid;
116 int do_read = 0;
117 int do_write = 0;
118 int do_cloexec = 0;
119 while (*mode != '\0')
120 switch (*mode++)
122 case 'r':
123 do_read = 1;
124 break;
125 case 'w':
126 do_write = 1;
127 break;
128 case 'e':
129 do_cloexec = 1;
130 break;
131 default:
132 errout:
133 __set_errno (EINVAL);
134 return NULL;
137 if ((do_read ^ do_write) == 0)
138 goto errout;
140 if (_IO_file_is_open (fp))
141 return NULL;
143 /* Atomically set the O_CLOEXEC flag for the pipe end used by the
144 child process (to avoid leaking the file descriptor in case of a
145 concurrent fork). This is later reverted in the child process.
146 When popen returns, the parent pipe end can be O_CLOEXEC or not,
147 depending on the 'e' open mode, but there is only one flag which
148 controls both descriptors. The parent end is adjusted below,
149 after creating the child process. (In the child process, the
150 parent end should be closed on execve, so O_CLOEXEC remains set
151 there.) */
152 if (__pipe2 (pipe_fds, O_CLOEXEC) < 0)
153 return NULL;
155 if (do_read)
157 parent_end = pipe_fds[0];
158 child_end = pipe_fds[1];
159 read_or_write = _IO_NO_WRITES;
161 else
163 parent_end = pipe_fds[1];
164 child_end = pipe_fds[0];
165 read_or_write = _IO_NO_READS;
168 ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
169 if (child_pid == 0)
171 int child_std_end = do_read ? 1 : 0;
172 struct _IO_proc_file *p;
174 if (child_end != child_std_end)
175 _IO_dup2 (child_end, child_std_end);
176 else
177 /* The descriptor is already the one we will use. But it must
178 not be marked close-on-exec. Undo the effects. */
179 __fcntl (child_end, F_SETFD, 0);
180 /* POSIX.2: "popen() shall ensure that any streams from previous
181 popen() calls that remain open in the parent process are closed
182 in the new child process." */
183 for (p = proc_file_chain; p; p = p->next)
185 int fd = _IO_fileno ((_IO_FILE *) p);
187 /* If any stream from previous popen() calls has fileno
188 child_std_end, it has been already closed by the dup2 syscall
189 above. */
190 if (fd != child_std_end)
191 _IO_close (fd);
194 _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
195 _IO__exit (127);
197 _IO_close (child_end);
198 if (child_pid < 0)
200 _IO_close (parent_end);
201 return NULL;
204 if (!do_cloexec)
205 /* Undo the effects of the pipe2 call which set the
206 close-on-exec flag. */
207 __fcntl (parent_end, F_SETFD, 0);
209 _IO_fileno (fp) = parent_end;
211 /* Link into proc_file_chain. */
212 #ifdef _IO_MTSAFE_IO
213 _IO_cleanup_region_start_noarg (unlock);
214 _IO_lock_lock (proc_file_chain_lock);
215 #endif
216 ((_IO_proc_file *) fp)->next = proc_file_chain;
217 proc_file_chain = (_IO_proc_file *) fp;
218 #ifdef _IO_MTSAFE_IO
219 _IO_lock_unlock (proc_file_chain_lock);
220 _IO_cleanup_region_end (0);
221 #endif
223 _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
224 return fp;
227 _IO_FILE *
228 _IO_new_popen (const char *command, const char *mode)
230 struct locked_FILE
232 struct _IO_proc_file fpx;
233 #ifdef _IO_MTSAFE_IO
234 _IO_lock_t lock;
235 #endif
236 } *new_f;
237 _IO_FILE *fp;
239 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
240 if (new_f == NULL)
241 return NULL;
242 #ifdef _IO_MTSAFE_IO
243 new_f->fpx.file.file._lock = &new_f->lock;
244 #endif
245 fp = &new_f->fpx.file.file;
246 _IO_init_internal (fp, 0);
247 _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps;
248 _IO_new_file_init_internal (&new_f->fpx.file);
249 #if !_IO_UNIFIED_JUMPTABLES
250 new_f->fpx.file.vtable = NULL;
251 #endif
252 if (_IO_new_proc_open (fp, command, mode) != NULL)
253 return (_IO_FILE *) &new_f->fpx.file;
254 _IO_un_link (&new_f->fpx.file);
255 free (new_f);
256 return NULL;
260 _IO_new_proc_close (_IO_FILE *fp)
262 /* This is not name-space clean. FIXME! */
263 int wstatus;
264 _IO_proc_file **ptr = &proc_file_chain;
265 _IO_pid_t wait_pid;
266 int status = -1;
268 /* Unlink from proc_file_chain. */
269 #ifdef _IO_MTSAFE_IO
270 _IO_cleanup_region_start_noarg (unlock);
271 _IO_lock_lock (proc_file_chain_lock);
272 #endif
273 for ( ; *ptr != NULL; ptr = &(*ptr)->next)
275 if (*ptr == (_IO_proc_file *) fp)
277 *ptr = (*ptr)->next;
278 status = 0;
279 break;
282 #ifdef _IO_MTSAFE_IO
283 _IO_lock_unlock (proc_file_chain_lock);
284 _IO_cleanup_region_end (0);
285 #endif
287 if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
288 return -1;
289 /* POSIX.2 Rationale: "Some historical implementations either block
290 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
291 for the child process to terminate. Since this behavior is not
292 described in POSIX.2, such implementations are not conforming." */
295 wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
297 while (wait_pid == -1 && errno == EINTR);
298 if (wait_pid == -1)
299 return -1;
300 return wstatus;
303 static const struct _IO_jump_t _IO_proc_jumps libio_vtable = {
304 JUMP_INIT_DUMMY,
305 JUMP_INIT(finish, _IO_new_file_finish),
306 JUMP_INIT(overflow, _IO_new_file_overflow),
307 JUMP_INIT(underflow, _IO_new_file_underflow),
308 JUMP_INIT(uflow, _IO_default_uflow),
309 JUMP_INIT(pbackfail, _IO_default_pbackfail),
310 JUMP_INIT(xsputn, _IO_new_file_xsputn),
311 JUMP_INIT(xsgetn, _IO_default_xsgetn),
312 JUMP_INIT(seekoff, _IO_new_file_seekoff),
313 JUMP_INIT(seekpos, _IO_default_seekpos),
314 JUMP_INIT(setbuf, _IO_new_file_setbuf),
315 JUMP_INIT(sync, _IO_new_file_sync),
316 JUMP_INIT(doallocate, _IO_file_doallocate),
317 JUMP_INIT(read, _IO_file_read),
318 JUMP_INIT(write, _IO_new_file_write),
319 JUMP_INIT(seek, _IO_file_seek),
320 JUMP_INIT(close, _IO_new_proc_close),
321 JUMP_INIT(stat, _IO_file_stat),
322 JUMP_INIT(showmanyc, _IO_default_showmanyc),
323 JUMP_INIT(imbue, _IO_default_imbue)
326 strong_alias (_IO_new_popen, __new_popen)
327 versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1);
328 versioned_symbol (libc, __new_popen, popen, GLIBC_2_1);
329 versioned_symbol (libc, _IO_new_proc_open, _IO_proc_open, GLIBC_2_1);
330 versioned_symbol (libc, _IO_new_proc_close, _IO_proc_close, GLIBC_2_1);