version 1.24, 2000/06/30 16:00:18 |
version 1.25, 2001/01/16 05:36:08 |
|
|
#include <sys/wait.h> |
#include <sys/wait.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <errno.h> |
#include <errno.h> |
|
#ifdef __STDC__ |
|
#include <stdarg.h> |
|
#else |
|
#include <varargs.h> |
|
#endif |
#include "extern.h" |
#include "extern.h" |
|
|
#define READ 0 |
#define READ 0 |
|
|
(void)fcntl(p[WRITE], F_SETFD, 1); |
(void)fcntl(p[WRITE], F_SETFD, 1); |
if (*mode == 'r') { |
if (*mode == 'r') { |
myside = p[READ]; |
myside = p[READ]; |
fd0 = -1; |
hisside = fd0 = fd1 = p[WRITE]; |
hisside = fd1 = p[WRITE]; |
|
} else { |
} else { |
myside = p[WRITE]; |
myside = p[WRITE]; |
hisside = fd0 = p[READ]; |
hisside = fd0 = p[READ]; |
fd1 = -1; |
fd1 = -1; |
} |
} |
sigemptyset(&nset); |
sigemptyset(&nset); |
if ((pid = start_command(cmd, &nset, fd0, fd1, NULL, NULL, NULL)) < 0) { |
if ((pid = start_command(value("SHELL"), &nset, fd0, fd1, |
|
"-c", cmd, NULL)) < 0) { |
(void)close(p[READ]); |
(void)close(p[READ]); |
(void)close(p[WRITE]); |
(void)close(p[WRITE]); |
return(NULL); |
return(NULL); |
|
|
* "nset" contains the signals to ignore in the new process. |
* "nset" contains the signals to ignore in the new process. |
* SIGINT is enabled unless it's in "nset". |
* SIGINT is enabled unless it's in "nset". |
*/ |
*/ |
/*VARARGS4*/ |
|
int |
int |
run_command(cmd, nset, infd, outfd, a0, a1, a2) |
start_commandv(cmd, nset, infd, outfd, args) |
char *cmd; |
char *cmd; |
sigset_t *nset; |
sigset_t *nset; |
int infd, outfd; |
int infd, outfd; |
char *a0, *a1, *a2; |
va_list args; |
{ |
{ |
int pid; |
int pid; |
|
|
if ((pid = start_command(cmd, nset, infd, outfd, a0, a1, a2)) < 0) |
if ((pid = fork()) < 0) { |
return(-1); |
|
return(wait_command(pid)); |
|
} |
|
|
|
/*VARARGS4*/ |
|
int |
|
start_command(cmd, nset, infd, outfd, a0, a1, a2) |
|
char *cmd; |
|
sigset_t *nset; |
|
int infd, outfd; |
|
char *a0, *a1, *a2; |
|
{ |
|
int pid; |
|
|
|
if ((pid = vfork()) < 0) { |
|
warn("fork"); |
warn("fork"); |
return(-1); |
return(-1); |
} |
} |
|
|
char *argv[100]; |
char *argv[100]; |
int i = getrawlist(cmd, argv, sizeof(argv)/ sizeof(*argv)); |
int i = getrawlist(cmd, argv, sizeof(argv)/ sizeof(*argv)); |
|
|
if ((argv[i++] = a0) != NULL && |
while ((argv[i++] = va_arg(args, char *))) |
(argv[i++] = a1) != NULL && |
; |
(argv[i++] = a2) != NULL) |
argv[i] = NULL; |
argv[i] = NULL; |
|
prepare_child(nset, infd, outfd); |
prepare_child(nset, infd, outfd); |
execvp(argv[0], argv); |
execvp(argv[0], argv); |
warn("%s", argv[0]); |
warn("%s", argv[0]); |
|
|
return(pid); |
return(pid); |
} |
} |
|
|
|
int |
|
#ifdef __STDC__ |
|
run_command(char *cmd, sigset_t *nset, int infd, int outfd, ...) |
|
#else |
|
run_command(cmd, nset, infd, outfd, va_alist) |
|
char *cmd; |
|
sigset_t *nset; |
|
int infd; |
|
int outfd; |
|
va_dcl |
|
#endif |
|
{ |
|
int pid; |
|
va_list args; |
|
|
|
#ifdef __STDC__ |
|
va_start(args, outfd); |
|
#else |
|
va_start(args); |
|
#endif |
|
pid = start_commandv(cmd, nset, infd, outfd, args); |
|
va_end(args); |
|
if (pid < 0) |
|
return(-1); |
|
return(wait_command(pid)); |
|
} |
|
|
|
int |
|
#ifdef __STDC__ |
|
start_command(char *cmd, sigset_t *nset, int infd, int outfd, ...) |
|
#else |
|
start_command(cmd, nset, infd, outfd, va_alist) |
|
char *cmd; |
|
sigset_t *nset; |
|
int infd; |
|
int outfd; |
|
va_dcl |
|
#endif |
|
{ |
|
va_list args; |
|
int r; |
|
|
|
#ifdef __STDC__ |
|
va_start(args, outfd); |
|
#else |
|
va_start(args); |
|
#endif |
|
r = start_commandv(cmd, nset, infd, outfd, args); |
|
va_end(args); |
|
return(r); |
|
} |
|
|
void |
void |
prepare_child(nset, infd, outfd) |
prepare_child(nset, infd, outfd) |
sigset_t *nset; |
sigset_t *nset; |
|
|
* All file descriptors other than 0, 1, and 2 are supposed to be |
* All file descriptors other than 0, 1, and 2 are supposed to be |
* close-on-exec. |
* close-on-exec. |
*/ |
*/ |
if (infd >= 0) |
if (infd >= 0) { |
dup2(infd, 0); |
dup2(infd, 0); |
|
} else { |
|
/* we don't want the child stealing my stdin input */ |
|
close(0); |
|
open(_PATH_DEVNULL, O_RDONLY, 0); |
|
} |
if (outfd >= 0) |
if (outfd >= 0) |
dup2(outfd, 1); |
dup2(outfd, 1); |
if (nset == NULL) |
if (nset == NULL) |
|
|
(void)Pclose(lockfp); |
(void)Pclose(lockfp); |
lockfp = NULL; |
lockfp = NULL; |
} else if (action == 1) { |
} else if (action == 1) { |
char *cmd = _PATH_LOCKSPOOL; |
char cmd[128]; |
|
|
/* XXX - lockspool requires root for user arg, we do not */ |
/* XXX - lockspool requires root for user arg, we do not */ |
if (uflag && asprintf(&cmd, "%s %s", _PATH_LOCKSPOOL, |
if (snprintf(cmd, sizeof(cmd), "%s %s", _PATH_LOCKSPOOL, uflag ? myname : "") < 0) |
myname) == -1) |
|
errx(1, "Out of memory"); |
errx(1, "Out of memory"); |
|
|
/* Create the lock */ |
/* Create the lock */ |
lockfp = Popen(cmd, "r"); |
lockfp = Popen(cmd, "r"); |
if (uflag) |
if (lockfp == NULL) |
free(cmd); |
return(0); |
if (lockfp == NULL || getc(lockfp) != '1') { |
if (getc(lockfp) != '1') { |
|
Pclose(lockfp); |
lockfp = NULL; |
lockfp = NULL; |
return(0); |
return(0); |
} |
} |