]>
git.saurik.com Git - apple/network_cmds.git/blob - ftpd.tproj/popen.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1988, 1993, 1994
26 * The Regents of the University of California. All rights reserved.
28 * This code is derived from software written by Ken Arnold and
29 * published in UNIX Review, Vol. 6, No. 8.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by the University of
42 * California, Berkeley and its contributors.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 static char sccsid
[] = "@(#)popen.c 8.3 (Berkeley) 4/6/94";
65 #include <sys/types.h>
79 * Special version of popen which avoids call to shell. This ensures noone
80 * may create a pipe to a hidden program as a side effect of a list or dir
87 ftpd_popen(program
, type
)
92 int argc
, gargc
, pdes
[2], pid
;
93 char **pop
, *argv
[100], *gargv
[1000];
95 if (*type
!= 'r' && *type
!= 'w' || type
[1])
99 if ((fds
= getdtablesize()) <= 0)
101 if ((pids
= (int *)malloc((u_int
)(fds
* sizeof(int)))) == NULL
)
103 memset(pids
, 0, fds
* sizeof(int));
108 /* break up string into pieces */
109 for (argc
= 0, cp
= program
;; cp
= NULL
)
110 if (!(argv
[argc
++] = strtok(cp
, " \t\n")))
113 /* glob each piece */
115 for (gargc
= argc
= 1; argv
[argc
]; argc
++) {
117 int flags
= GLOB_BRACE
|GLOB_NOCHECK
|GLOB_QUOTE
|GLOB_TILDE
;
119 memset(&gl
, 0, sizeof(gl
));
120 if (glob(argv
[argc
], flags
, NULL
, &gl
))
121 gargv
[gargc
++] = strdup(argv
[argc
]);
123 for (pop
= gl
.gl_pathv
; *pop
; pop
++)
124 gargv
[gargc
++] = strdup(*pop
);
130 switch(pid
= vfork()) {
132 (void)close(pdes
[0]);
133 (void)close(pdes
[1]);
138 if (pdes
[1] != STDOUT_FILENO
) {
139 dup2(pdes
[1], STDOUT_FILENO
);
140 (void)close(pdes
[1]);
142 dup2(STDOUT_FILENO
, STDERR_FILENO
); /* stderr too! */
143 (void)close(pdes
[0]);
145 if (pdes
[0] != STDIN_FILENO
) {
146 dup2(pdes
[0], STDIN_FILENO
);
147 (void)close(pdes
[0]);
149 (void)close(pdes
[1]);
151 execv(gargv
[0], gargv
);
154 /* parent; assume fdopen can't fail... */
156 iop
= fdopen(pdes
[0], type
);
157 (void)close(pdes
[1]);
159 iop
= fdopen(pdes
[1], type
);
160 (void)close(pdes
[0]);
162 pids
[fileno(iop
)] = pid
;
164 pfree
: for (argc
= 1; gargv
[argc
] != NULL
; argc
++)
174 int fdes
, omask
, status
;
178 * pclose returns -1 if stream is not associated with a
179 * `popened' command, or, if already `pclosed'.
181 if (pids
== 0 || pids
[fdes
= fileno(iop
)] == 0)
184 omask
= sigblock(sigmask(SIGINT
)|sigmask(SIGQUIT
)|sigmask(SIGHUP
));
185 while ((pid
= waitpid(pids
[fdes
], &status
, 0)) < 0 && errno
== EINTR
)
187 (void)sigsetmask(omask
);
191 if (WIFEXITED(status
))
192 return (WEXITSTATUS(status
));