* Copyright (c) 1980 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)popen.c 5.16 (Berkeley) 4/1/91";
static struct fp
*fp_head
;
if ((fp
= fopen(file
, mode
)) != NULL
)
if ((fp
= fdopen(fd
, mode
)) != NULL
)
int myside
, hisside
, fd0
, fd1
;
pid
= (int *) malloc((unsigned) sizeof (int) * getdtablesize());
hisside
= fd1
= p
[WRITE
];
if ((pid
[myside
] = start_command(cmd
, 0, fd0
, fd1
, NOSTR
)) < 0) {
if ((fp
= fdopen(myside
, mode
)) != NULL
)
omask
= sigblock(sigmask(SIGINT
)|sigmask(SIGHUP
));
(void) Pclose(fp_head
->fp
);
(void) Fclose(fp_head
->fp
);
if ((fpp
= (struct fp
*) malloc(sizeof *fpp
)) == NULL
)
for (pp
= &fp_head
; p
= *pp
; pp
= &p
->link
)
* Ignore this for now; there may still be uncaught
panic("Invalid file pointer");
* Run a command without a shell, with optional arguments and splicing
* of stdin and stdout. The command name can be a sequence of words.
* Signals must be handled by the caller.
* "Mask" contains the signals to ignore in the new process.
* SIGINT is enabled unless it's in the mask.
run_command(cmd
, mask
, infd
, outfd
, a0
, a1
, a2
)
if ((pid
= start_command(cmd
, mask
, infd
, outfd
, a0
, a1
, a2
)) < 0)
return wait_command(pid
);
start_command(cmd
, mask
, infd
, outfd
, a0
, a1
, a2
)
if ((pid
= vfork()) < 0) {
int i
= getrawlist(cmd
, argv
, sizeof argv
/ sizeof *argv
);
if ((argv
[i
++] = a0
) != NOSTR
&&
(argv
[i
++] = a1
) != NOSTR
&&
(argv
[i
++] = a2
) != NOSTR
)
prepare_child(mask
, infd
, outfd
);
prepare_child(mask
, infd
, outfd
)
for (i
= getdtablesize(); --i
> 2;)
for (i
= 1; i
<= NSIG
; i
++)
(void) signal(i
, SIG_IGN
);
if ((mask
& sigmask(SIGINT
)) == 0)
(void) signal(SIGINT
, SIG_DFL
);
if (wait_child(pid
) < 0) {
printf("Fatal error in process.\n");
static struct child
*child
;
register struct child
**cpp
;
for (cpp
= &child
; *cpp
!= NULL
&& (*cpp
)->pid
!= pid
;
*cpp
= (struct child
*) malloc(sizeof (struct child
));
(*cpp
)->done
= (*cpp
)->free
= 0;
register struct child
*cp
;
register struct child
**cpp
;
for (cpp
= &child
; *cpp
!= cp
; cpp
= &(*cpp
)->link
)
register struct child
*cp
;
wait3((int *)&status
, WNOHANG
, (struct rusage
*)0)) > 0) {
* Wait for a specific child to die.
int mask
= sigblock(sigmask(SIGCHLD
));
register struct child
*cp
= findchild(pid
);
wait_status
= cp
->status
;
return wait_status
.w_status
? -1 : 0;
* Mark a child as don't care.
int mask
= sigblock(sigmask(SIGCHLD
));
register struct child
*cp
= findchild(pid
);