1 /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
25 #include <sys/types.h>
30 #define SH_PATH "/bin/sh" /* Shell to run. */
31 #define SH_NAME "sh" /* Name to give it. */
33 /* Structure describing a popen child. */
36 pid_t pid
; /* PID of the child. */
37 __ptr_t cookie
; /* Original cookie from fdopen. */
38 __io_functions funcs
; /* Original functions from fdopen. */
41 /* io_functions for pipe streams.
42 These all simply call the corresponding
43 original function with the original cookie. */
45 #define FUNC(type, name, args) \
46 static type DEFUN(__CONCAT(child_,name), args, __CONCAT(name,decl)) \
48 struct child *c = (struct child *) cookie; \
50 __ptr_t cookie = c->cookie; \
51 return (*c->funcs.__CONCAT(__,name)) args; \
55 #define readdecl PTR cookie AND register char *buf AND register size_t n
56 FUNC (int, read
, (cookie
, buf
, n
))
57 #define writedecl PTR cookie AND register CONST char *buf AND register size_t n
58 FUNC (int, write
, (cookie
, buf
, n
))
59 #define seekdecl PTR cookie AND fpos_t *pos AND int whence
60 FUNC (int, seek
, (cookie
, pos
, whence
))
61 #define closedecl PTR cookie
62 FUNC (int, close
, (cookie
))
63 #define filenodecl PTR cookie
64 FUNC (int, fileno
, (cookie
))
66 static const __io_functions child_funcs
67 = { child_read
, child_write
, child_seek
, child_close
, child_fileno
};
69 /* Open a new stream that is a one-way pipe to a
70 child process running the given shell command. */
72 DEFUN(popen
, (command
, mode
), CONST
char *command AND CONST
char *mode
)
79 if (command
== NULL
|| mode
== NULL
|| (*mode
!= 'r' && *mode
!= 'w'))
85 /* Create the pipe. */
86 if (pipe(pipedes
) < 0)
89 /* Fork off the child. */
91 if (pid
== (pid_t
) -1)
93 /* The fork failed. */
94 (void) close (pipedes
[0]);
95 (void) close (pipedes
[1]);
98 else if (pid
== (pid_t
) 0)
100 /* We are the child side. Make the write side of
101 the pipe be stdin or the read side be stdout. */
103 CONST
char *new_argv
[4];
105 if ((*mode
== 'w' ? dup2(pipedes
[STDIN_FILENO
], STDIN_FILENO
) :
106 dup2(pipedes
[STDOUT_FILENO
], STDOUT_FILENO
)) < 0)
109 /* Close the pipe descriptors. */
110 (void) close(pipedes
[STDIN_FILENO
]);
111 (void) close(pipedes
[STDOUT_FILENO
]);
113 /* Exec the shell. */
114 new_argv
[0] = SH_NAME
;
116 new_argv
[2] = command
;
118 (void) execve(SH_PATH
, (char *CONST
*) new_argv
, environ
);
119 /* Die if it failed. */
123 /* We are the parent side. */
125 /* Close the irrelevant side of the pipe and open the relevant side as a
126 new stream. Mark our side of the pipe to close on exec, so new children
130 (void) close (pipedes
[STDOUT_FILENO
]);
131 (void) fcntl (pipedes
[STDIN_FILENO
], F_SETFD
, FD_CLOEXEC
);
132 stream
= fdopen (pipedes
[STDIN_FILENO
], mode
);
136 (void) close (pipedes
[STDIN_FILENO
]);
137 (void) fcntl (pipedes
[STDOUT_FILENO
], F_SETFD
, FD_CLOEXEC
);
138 stream
= fdopen (pipedes
[STDOUT_FILENO
], mode
);
144 child
= (struct child
*) malloc (sizeof (struct child
));
149 /* Make sure STREAM has its functions set before
150 we try to squirrel them away in CHILD. */
151 extern void __stdio_check_funcs
__P ((FILE *));
152 __stdio_check_funcs (stream
);
156 child
->cookie
= stream
->__cookie
;
157 child
->funcs
= stream
->__io_funcs
;
158 stream
->__cookie
= (PTR
) child
;
159 stream
->__io_funcs
= child_funcs
;
160 stream
->__ispipe
= 1;
165 /* The stream couldn't be opened or the child structure couldn't be
166 allocated. Kill the child and close the other side of the pipe. */
168 (void) kill (pid
, SIGKILL
);
170 (void) close (pipedes
[*mode
== 'r' ? STDOUT_FILENO
: STDIN_FILENO
]);
172 (void) fclose (stream
);
174 (void) waitpid (pid
, (int *) NULL
, 0);
179 dead
= wait ((int *) NULL
);
180 while (dead
> 0 && dead
!= pid
);
188 /* Close a stream opened by popen and return its status.
189 Returns -1 if the stream was not opened by popen. */
191 DEFUN(pclose
, (stream
), register FILE *stream
)
197 if (!__validfp(stream
) || !stream
->__ispipe
)
203 c
= (struct child
*) stream
->__cookie
;
205 stream
->__cookie
= c
->cookie
;
206 stream
->__io_funcs
= c
->funcs
;
208 stream
->__ispipe
= 0;
213 dead
= waitpid (pid
, &status
, 0);
216 dead
= wait (&status
);
217 while (dead
> 0 && dead
!= pid
);