* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)popen.c 8.1 (Berkeley) %G%";
static struct fp
*fp_head
;
static struct child
*child
;
static struct child
*findchild
__P((int));
static void delchild
__P((struct child
*));
if ((fp
= fopen(file
, mode
)) != NULL
) {
(void) fcntl(fileno(fp
), F_SETFD
, 1);
if ((fp
= fdopen(fd
, mode
)) != NULL
) {
(void) fcntl(fileno(fp
), F_SETFD
, 1);
int myside
, hisside
, fd0
, fd1
;
(void) fcntl(p
[READ
], F_SETFD
, 1);
(void) fcntl(p
[WRITE
], F_SETFD
, 1);
hisside
= fd1
= p
[WRITE
];
if ((pid
= start_command(cmd
, 0, fd0
, fd1
, NOSTR
, NOSTR
, NOSTR
)) < 0) {
if ((fp
= fdopen(myside
, mode
)) != NULL
)
register_file(fp
, 1, pid
);
omask
= sigblock(sigmask(SIGINT
)|sigmask(SIGHUP
));
(void) Pclose(fp_head
->fp
);
(void) Fclose(fp_head
->fp
);
register_file(fp
, pipe
, pid
)
if ((fpp
= (struct fp
*) malloc(sizeof *fpp
)) == NULL
)
for (pp
= &fp_head
; p
= *pp
; pp
= &p
->link
)
panic("Invalid file pointer");
for (p
= fp_head
; p
; p
= p
->link
)
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
)
* All file descriptors other than 0, 1, and 2 are supposed to be
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");
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
);