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