Hurd: Fix mlock in all cases except non-readable pages.
[glibc.git] / libio / iopopen.c
blob967473d9c52a657ca4d25636ce9548cb7b986c65
1 /* Copyright (C) 1993, 1997-2002, 2003, 2004, 2007, 2008, 2012
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, see
18 <http://www.gnu.org/licenses/>.
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 #ifndef _POSIX_SOURCE
30 # define _POSIX_SOURCE
31 #endif
32 #include "libioP.h"
33 #if _IO_HAVE_SYS_WAIT
34 #include <signal.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #ifdef _LIBC
38 # include <unistd.h>
39 # include <shlib-compat.h>
40 # include <not-cancel.h>
41 #endif
42 #include <sys/types.h>
43 #include <sys/wait.h>
44 #include <kernel-features.h>
46 #ifndef _IO_fork
47 #ifdef _LIBC
48 #define _IO_fork __fork
49 #else
50 #define _IO_fork fork /* defined in libiberty, if needed */
51 #endif
52 extern _IO_pid_t _IO_fork (void) __THROW;
53 #endif
55 #endif /* _IO_HAVE_SYS_WAIT */
57 #ifndef _IO_dup2
58 #ifdef _LIBC
59 #define _IO_dup2 __dup2
60 #else
61 #define _IO_dup2 dup2
62 #endif
63 extern int _IO_dup2 (int fd, int fd2) __THROW;
64 #endif
66 #ifndef _IO_waitpid
67 #ifdef _LIBC
68 #define _IO_waitpid waitpid_not_cancel
69 #else
70 #define _IO_waitpid waitpid
71 #endif
72 #endif
74 #ifndef _IO_execl
75 #define _IO_execl execl
76 #endif
77 #ifndef _IO__exit
78 #define _IO__exit _exit
79 #endif
81 #ifndef _IO_close
82 #ifdef _LIBC
83 #define _IO_close close_not_cancel
84 #else
85 #define _IO_close close
86 #endif
87 #endif
89 struct _IO_proc_file
91 struct _IO_FILE_plus file;
92 /* Following fields must match those in class procbuf (procbuf.h) */
93 _IO_pid_t pid;
94 struct _IO_proc_file *next;
96 typedef struct _IO_proc_file _IO_proc_file;
98 static const struct _IO_jump_t _IO_proc_jumps;
100 static struct _IO_proc_file *proc_file_chain;
102 #ifdef _IO_MTSAFE_IO
103 static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer;
105 static void
106 unlock (void *not_used)
108 _IO_lock_unlock (proc_file_chain_lock);
110 #endif
112 _IO_FILE *
113 _IO_new_proc_open (fp, command, mode)
114 _IO_FILE *fp;
115 const char *command;
116 const char *mode;
118 #if _IO_HAVE_SYS_WAIT
119 int read_or_write;
120 int parent_end, child_end;
121 int pipe_fds[2];
122 _IO_pid_t child_pid;
124 int do_read = 0;
125 int do_write = 0;
126 int do_cloexec = 0;
127 while (*mode != '\0')
128 switch (*mode++)
130 case 'r':
131 do_read = 1;
132 break;
133 case 'w':
134 do_write = 1;
135 break;
136 case 'e':
137 do_cloexec = 1;
138 break;
139 default:
140 errout:
141 __set_errno (EINVAL);
142 return NULL;
145 if ((do_read ^ do_write) == 0)
146 goto errout;
148 if (_IO_file_is_open (fp))
149 return NULL;
151 #ifdef O_CLOEXEC
152 # ifndef __ASSUME_PIPE2
153 if (__have_pipe2 >= 0)
154 # endif
156 int r = __pipe2 (pipe_fds, O_CLOEXEC);
157 # ifndef __ASSUME_PIPE2
158 if (__have_pipe2 == 0)
159 __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1;
161 if (__have_pipe2 > 0)
162 # endif
163 if (r < 0)
164 return NULL;
166 #endif
167 #ifndef __ASSUME_PIPE2
168 # ifdef O_CLOEXEC
169 if (__have_pipe2 < 0)
170 # endif
171 if (__pipe (pipe_fds) < 0)
172 return NULL;
173 #endif
175 if (do_read)
177 parent_end = pipe_fds[0];
178 child_end = pipe_fds[1];
179 read_or_write = _IO_NO_WRITES;
181 else
183 parent_end = pipe_fds[1];
184 child_end = pipe_fds[0];
185 read_or_write = _IO_NO_READS;
188 ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
189 if (child_pid == 0)
191 int child_std_end = do_read ? 1 : 0;
192 struct _IO_proc_file *p;
194 #ifndef __ASSUME_PIPE2
195 /* If we have pipe2 the descriptor is marked for close-on-exec. */
196 _IO_close (parent_end);
197 #endif
198 if (child_end != child_std_end)
200 _IO_dup2 (child_end, child_std_end);
201 #ifndef __ASSUME_PIPE2
202 _IO_close (child_end);
203 #endif
205 #ifdef O_CLOEXEC
206 else
208 /* The descriptor is already the one we will use. But it must
209 not be marked close-on-exec. Undo the effects. */
210 # ifndef __ASSUME_PIPE2
211 if (__have_pipe2 > 0)
212 # endif
213 __fcntl (child_end, F_SETFD, 0);
215 #endif
216 /* POSIX.2: "popen() shall ensure that any streams from previous
217 popen() calls that remain open in the parent process are closed
218 in the new child process." */
219 for (p = proc_file_chain; p; p = p->next)
221 int fd = _IO_fileno ((_IO_FILE *) p);
223 /* If any stream from previous popen() calls has fileno
224 child_std_end, it has been already closed by the dup2 syscall
225 above. */
226 if (fd != child_std_end)
227 _IO_close (fd);
230 _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
231 _IO__exit (127);
233 _IO_close (child_end);
234 if (child_pid < 0)
236 _IO_close (parent_end);
237 return NULL;
240 if (do_cloexec)
242 #ifndef __ASSUME_PIPE2
243 # ifdef O_CLOEXEC
244 if (__have_pipe2 < 0)
245 # endif
246 __fcntl (parent_end, F_SETFD, FD_CLOEXEC);
247 #endif
249 else
251 #ifdef O_CLOEXEC
252 /* Undo the effects of the pipe2 call which set the
253 close-on-exec flag. */
254 # ifndef __ASSUME_PIPE2
255 if (__have_pipe2 > 0)
256 # endif
257 __fcntl (parent_end, F_SETFD, 0);
258 #endif
261 _IO_fileno (fp) = parent_end;
263 /* Link into proc_file_chain. */
264 #ifdef _IO_MTSAFE_IO
265 _IO_cleanup_region_start_noarg (unlock);
266 _IO_lock_lock (proc_file_chain_lock);
267 #endif
268 ((_IO_proc_file *) fp)->next = proc_file_chain;
269 proc_file_chain = (_IO_proc_file *) fp;
270 #ifdef _IO_MTSAFE_IO
271 _IO_lock_unlock (proc_file_chain_lock);
272 _IO_cleanup_region_end (0);
273 #endif
275 _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
276 return fp;
277 #else /* !_IO_HAVE_SYS_WAIT */
278 return NULL;
279 #endif
282 _IO_FILE *
283 _IO_new_popen (command, mode)
284 const char *command;
285 const char *mode;
287 struct locked_FILE
289 struct _IO_proc_file fpx;
290 #ifdef _IO_MTSAFE_IO
291 _IO_lock_t lock;
292 #endif
293 } *new_f;
294 _IO_FILE *fp;
296 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
297 if (new_f == NULL)
298 return NULL;
299 #ifdef _IO_MTSAFE_IO
300 new_f->fpx.file.file._lock = &new_f->lock;
301 #endif
302 fp = &new_f->fpx.file.file;
303 INTUSE(_IO_init) (fp, 0);
304 _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps;
305 _IO_new_file_init (&new_f->fpx.file);
306 #if !_IO_UNIFIED_JUMPTABLES
307 new_f->fpx.file.vtable = NULL;
308 #endif
309 if (_IO_new_proc_open (fp, command, mode) != NULL)
310 return (_IO_FILE *) &new_f->fpx.file;
311 INTUSE(_IO_un_link) (&new_f->fpx.file);
312 free (new_f);
313 return NULL;
317 _IO_new_proc_close (fp)
318 _IO_FILE *fp;
320 /* This is not name-space clean. FIXME! */
321 #if _IO_HAVE_SYS_WAIT
322 int wstatus;
323 _IO_proc_file **ptr = &proc_file_chain;
324 _IO_pid_t wait_pid;
325 int status = -1;
327 /* Unlink from proc_file_chain. */
328 #ifdef _IO_MTSAFE_IO
329 _IO_cleanup_region_start_noarg (unlock);
330 _IO_lock_lock (proc_file_chain_lock);
331 #endif
332 for ( ; *ptr != NULL; ptr = &(*ptr)->next)
334 if (*ptr == (_IO_proc_file *) fp)
336 *ptr = (*ptr)->next;
337 status = 0;
338 break;
341 #ifdef _IO_MTSAFE_IO
342 _IO_lock_unlock (proc_file_chain_lock);
343 _IO_cleanup_region_end (0);
344 #endif
346 if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
347 return -1;
348 /* POSIX.2 Rationale: "Some historical implementations either block
349 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
350 for the child process to terminate. Since this behavior is not
351 described in POSIX.2, such implementations are not conforming." */
354 wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
356 while (wait_pid == -1 && errno == EINTR);
357 if (wait_pid == -1)
358 return -1;
359 return wstatus;
360 #else /* !_IO_HAVE_SYS_WAIT */
361 return -1;
362 #endif
365 static const struct _IO_jump_t _IO_proc_jumps = {
366 JUMP_INIT_DUMMY,
367 JUMP_INIT(finish, _IO_new_file_finish),
368 JUMP_INIT(overflow, _IO_new_file_overflow),
369 JUMP_INIT(underflow, _IO_new_file_underflow),
370 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
371 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
372 JUMP_INIT(xsputn, _IO_new_file_xsputn),
373 JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
374 JUMP_INIT(seekoff, _IO_new_file_seekoff),
375 JUMP_INIT(seekpos, _IO_default_seekpos),
376 JUMP_INIT(setbuf, _IO_new_file_setbuf),
377 JUMP_INIT(sync, _IO_new_file_sync),
378 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
379 JUMP_INIT(read, INTUSE(_IO_file_read)),
380 JUMP_INIT(write, _IO_new_file_write),
381 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
382 JUMP_INIT(close, _IO_new_proc_close),
383 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
384 JUMP_INIT(showmanyc, _IO_default_showmanyc),
385 JUMP_INIT(imbue, _IO_default_imbue)
388 strong_alias (_IO_new_popen, __new_popen)
389 versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1);
390 versioned_symbol (libc, __new_popen, popen, GLIBC_2_1);
391 versioned_symbol (libc, _IO_new_proc_open, _IO_proc_open, GLIBC_2_1);
392 versioned_symbol (libc, _IO_new_proc_close, _IO_proc_close, GLIBC_2_1);