Shrink heap on linux when overcommit_memory == 2
[glibc.git] / libio / iopopen.c
blob7163958047db7c006e48188aa5bfc4cd3dc879ab
1 /* Copyright (C) 1993-2012 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 <signal.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #ifdef _LIBC
36 # include <unistd.h>
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 (fp, command, mode)
110 _IO_FILE *fp;
111 const char *command;
112 const char *mode;
114 int read_or_write;
115 int parent_end, child_end;
116 int pipe_fds[2];
117 _IO_pid_t child_pid;
119 int do_read = 0;
120 int do_write = 0;
121 int do_cloexec = 0;
122 while (*mode != '\0')
123 switch (*mode++)
125 case 'r':
126 do_read = 1;
127 break;
128 case 'w':
129 do_write = 1;
130 break;
131 case 'e':
132 do_cloexec = 1;
133 break;
134 default:
135 errout:
136 __set_errno (EINVAL);
137 return NULL;
140 if ((do_read ^ do_write) == 0)
141 goto errout;
143 if (_IO_file_is_open (fp))
144 return NULL;
146 #ifdef O_CLOEXEC
147 # ifndef __ASSUME_PIPE2
148 if (__have_pipe2 >= 0)
149 # endif
151 int r = __pipe2 (pipe_fds, O_CLOEXEC);
152 # ifndef __ASSUME_PIPE2
153 if (__have_pipe2 == 0)
154 __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1;
156 if (__have_pipe2 > 0)
157 # endif
158 if (r < 0)
159 return NULL;
161 #endif
162 #ifndef __ASSUME_PIPE2
163 # ifdef O_CLOEXEC
164 if (__have_pipe2 < 0)
165 # endif
166 if (__pipe (pipe_fds) < 0)
167 return NULL;
168 #endif
170 if (do_read)
172 parent_end = pipe_fds[0];
173 child_end = pipe_fds[1];
174 read_or_write = _IO_NO_WRITES;
176 else
178 parent_end = pipe_fds[1];
179 child_end = pipe_fds[0];
180 read_or_write = _IO_NO_READS;
183 ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
184 if (child_pid == 0)
186 int child_std_end = do_read ? 1 : 0;
187 struct _IO_proc_file *p;
189 #ifndef __ASSUME_PIPE2
190 /* If we have pipe2 the descriptor is marked for close-on-exec. */
191 _IO_close (parent_end);
192 #endif
193 if (child_end != child_std_end)
195 _IO_dup2 (child_end, child_std_end);
196 #ifndef __ASSUME_PIPE2
197 _IO_close (child_end);
198 #endif
200 #ifdef O_CLOEXEC
201 else
203 /* The descriptor is already the one we will use. But it must
204 not be marked close-on-exec. Undo the effects. */
205 # ifndef __ASSUME_PIPE2
206 if (__have_pipe2 > 0)
207 # endif
208 __fcntl (child_end, F_SETFD, 0);
210 #endif
211 /* POSIX.2: "popen() shall ensure that any streams from previous
212 popen() calls that remain open in the parent process are closed
213 in the new child process." */
214 for (p = proc_file_chain; p; p = p->next)
216 int fd = _IO_fileno ((_IO_FILE *) p);
218 /* If any stream from previous popen() calls has fileno
219 child_std_end, it has been already closed by the dup2 syscall
220 above. */
221 if (fd != child_std_end)
222 _IO_close (fd);
225 _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
226 _IO__exit (127);
228 _IO_close (child_end);
229 if (child_pid < 0)
231 _IO_close (parent_end);
232 return NULL;
235 if (do_cloexec)
237 #ifndef __ASSUME_PIPE2
238 # ifdef O_CLOEXEC
239 if (__have_pipe2 < 0)
240 # endif
241 __fcntl (parent_end, F_SETFD, FD_CLOEXEC);
242 #endif
244 else
246 #ifdef O_CLOEXEC
247 /* Undo the effects of the pipe2 call which set the
248 close-on-exec flag. */
249 # ifndef __ASSUME_PIPE2
250 if (__have_pipe2 > 0)
251 # endif
252 __fcntl (parent_end, F_SETFD, 0);
253 #endif
256 _IO_fileno (fp) = parent_end;
258 /* Link into proc_file_chain. */
259 #ifdef _IO_MTSAFE_IO
260 _IO_cleanup_region_start_noarg (unlock);
261 _IO_lock_lock (proc_file_chain_lock);
262 #endif
263 ((_IO_proc_file *) fp)->next = proc_file_chain;
264 proc_file_chain = (_IO_proc_file *) fp;
265 #ifdef _IO_MTSAFE_IO
266 _IO_lock_unlock (proc_file_chain_lock);
267 _IO_cleanup_region_end (0);
268 #endif
270 _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
271 return fp;
274 _IO_FILE *
275 _IO_new_popen (command, mode)
276 const char *command;
277 const char *mode;
279 struct locked_FILE
281 struct _IO_proc_file fpx;
282 #ifdef _IO_MTSAFE_IO
283 _IO_lock_t lock;
284 #endif
285 } *new_f;
286 _IO_FILE *fp;
288 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
289 if (new_f == NULL)
290 return NULL;
291 #ifdef _IO_MTSAFE_IO
292 new_f->fpx.file.file._lock = &new_f->lock;
293 #endif
294 fp = &new_f->fpx.file.file;
295 _IO_init (fp, 0);
296 _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps;
297 _IO_new_file_init (&new_f->fpx.file);
298 #if !_IO_UNIFIED_JUMPTABLES
299 new_f->fpx.file.vtable = NULL;
300 #endif
301 if (_IO_new_proc_open (fp, command, mode) != NULL)
302 return (_IO_FILE *) &new_f->fpx.file;
303 _IO_un_link (&new_f->fpx.file);
304 free (new_f);
305 return NULL;
309 _IO_new_proc_close (fp)
310 _IO_FILE *fp;
312 /* This is not name-space clean. FIXME! */
313 int wstatus;
314 _IO_proc_file **ptr = &proc_file_chain;
315 _IO_pid_t wait_pid;
316 int status = -1;
318 /* Unlink from proc_file_chain. */
319 #ifdef _IO_MTSAFE_IO
320 _IO_cleanup_region_start_noarg (unlock);
321 _IO_lock_lock (proc_file_chain_lock);
322 #endif
323 for ( ; *ptr != NULL; ptr = &(*ptr)->next)
325 if (*ptr == (_IO_proc_file *) fp)
327 *ptr = (*ptr)->next;
328 status = 0;
329 break;
332 #ifdef _IO_MTSAFE_IO
333 _IO_lock_unlock (proc_file_chain_lock);
334 _IO_cleanup_region_end (0);
335 #endif
337 if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
338 return -1;
339 /* POSIX.2 Rationale: "Some historical implementations either block
340 or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
341 for the child process to terminate. Since this behavior is not
342 described in POSIX.2, such implementations are not conforming." */
345 wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
347 while (wait_pid == -1 && errno == EINTR);
348 if (wait_pid == -1)
349 return -1;
350 return wstatus;
353 static const struct _IO_jump_t _IO_proc_jumps = {
354 JUMP_INIT_DUMMY,
355 JUMP_INIT(finish, _IO_new_file_finish),
356 JUMP_INIT(overflow, _IO_new_file_overflow),
357 JUMP_INIT(underflow, _IO_new_file_underflow),
358 JUMP_INIT(uflow, _IO_default_uflow),
359 JUMP_INIT(pbackfail, _IO_default_pbackfail),
360 JUMP_INIT(xsputn, _IO_new_file_xsputn),
361 JUMP_INIT(xsgetn, _IO_default_xsgetn),
362 JUMP_INIT(seekoff, _IO_new_file_seekoff),
363 JUMP_INIT(seekpos, _IO_default_seekpos),
364 JUMP_INIT(setbuf, _IO_new_file_setbuf),
365 JUMP_INIT(sync, _IO_new_file_sync),
366 JUMP_INIT(doallocate, _IO_file_doallocate),
367 JUMP_INIT(read, _IO_file_read),
368 JUMP_INIT(write, _IO_new_file_write),
369 JUMP_INIT(seek, _IO_file_seek),
370 JUMP_INIT(close, _IO_new_proc_close),
371 JUMP_INIT(stat, _IO_file_stat),
372 JUMP_INIT(showmanyc, _IO_default_showmanyc),
373 JUMP_INIT(imbue, _IO_default_imbue)
376 strong_alias (_IO_new_popen, __new_popen)
377 versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1);
378 versioned_symbol (libc, __new_popen, popen, GLIBC_2_1);
379 versioned_symbol (libc, _IO_new_proc_open, _IO_proc_open, GLIBC_2_1);
380 versioned_symbol (libc, _IO_new_proc_close, _IO_proc_close, GLIBC_2_1);