rename check_status to wait_for_process, and export it; function
pipe_execv similar to popen, but with more control over input and output git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@10132 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -64,8 +64,8 @@ RCSID("$Id$");
|
||||
128- is 128 + signal that killed subprocess
|
||||
*/
|
||||
|
||||
static int
|
||||
check_status(pid_t pid)
|
||||
int
|
||||
wait_for_process(pid_t pid)
|
||||
{
|
||||
while(1) {
|
||||
int status;
|
||||
@@ -82,6 +82,94 @@ check_status(pid_t pid)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pipe_execv(FILE **stdin_fd, FILE **stdout_fd, FILE **stderr_fd,
|
||||
const char *file, ...)
|
||||
{
|
||||
int in_fd[2], out_fd[2], err_fd[2];
|
||||
pid_t pid;
|
||||
va_list ap;
|
||||
char **argv;
|
||||
int ret;
|
||||
|
||||
if(stdin_fd != NULL)
|
||||
pipe(in_fd);
|
||||
if(stdout_fd != NULL)
|
||||
pipe(out_fd);
|
||||
if(stderr_fd != NULL)
|
||||
pipe(err_fd);
|
||||
pid = fork();
|
||||
switch(pid) {
|
||||
case 0:
|
||||
va_start(ap, file);
|
||||
argv = vstrcollect(&ap);
|
||||
va_end(ap);
|
||||
if(argv == NULL)
|
||||
exit(-1);
|
||||
|
||||
/* close pipes we're not interested in */
|
||||
if(stdin_fd != NULL)
|
||||
close(in_fd[1]);
|
||||
if(stdout_fd != NULL)
|
||||
close(out_fd[0]);
|
||||
if(stderr_fd != NULL)
|
||||
close(err_fd[0]);
|
||||
|
||||
/* pipe everything caller doesn't care about to /dev/null */
|
||||
if(stdin_fd == NULL)
|
||||
in_fd[0] = open(_PATH_DEVNULL, O_RDONLY);
|
||||
if(stdout_fd == NULL)
|
||||
out_fd[1] = open(_PATH_DEVNULL, O_WRONLY);
|
||||
if(stderr_fd == NULL)
|
||||
err_fd[1] = open(_PATH_DEVNULL, O_WRONLY);
|
||||
|
||||
/* move to proper descriptors */
|
||||
if(in_fd[0] != STDIN_FILENO) {
|
||||
dup2(in_fd[0], STDIN_FILENO);
|
||||
close(in_fd[0]);
|
||||
}
|
||||
if(out_fd[1] != STDOUT_FILENO) {
|
||||
dup2(out_fd[1], STDOUT_FILENO);
|
||||
close(out_fd[1]);
|
||||
}
|
||||
if(err_fd[1] != STDERR_FILENO) {
|
||||
dup2(err_fd[1], STDERR_FILENO);
|
||||
close(err_fd[1]);
|
||||
}
|
||||
|
||||
execv(file, argv);
|
||||
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
||||
case -1:
|
||||
if(stdin_fd != NULL) {
|
||||
close(in_fd[0]);
|
||||
close(in_fd[1]);
|
||||
}
|
||||
if(stdout_fd != NULL) {
|
||||
close(out_fd[0]);
|
||||
close(out_fd[1]);
|
||||
}
|
||||
if(stderr_fd != NULL) {
|
||||
close(err_fd[0]);
|
||||
close(err_fd[1]);
|
||||
}
|
||||
return -2;
|
||||
default:
|
||||
if(stdin_fd != NULL) {
|
||||
close(in_fd[0]);
|
||||
*stdin_fd = fdopen(in_fd[1], "w");
|
||||
}
|
||||
if(stdout_fd != NULL) {
|
||||
close(out_fd[1]);
|
||||
*stdout_fd = fdopen(out_fd[0], "r");
|
||||
}
|
||||
if(stderr_fd != NULL) {
|
||||
close(err_fd[1]);
|
||||
*stderr_fd = fdopen(err_fd[0], "r");
|
||||
}
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
int
|
||||
simple_execvp(const char *file, char *const args[])
|
||||
{
|
||||
@@ -93,7 +181,7 @@ simple_execvp(const char *file, char *const args[])
|
||||
execvp(file, args);
|
||||
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
||||
default:
|
||||
return check_status(pid);
|
||||
return wait_for_process(pid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +197,7 @@ simple_execve(const char *file, char *const args[], char *const envp[])
|
||||
execve(file, args, envp);
|
||||
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
||||
default:
|
||||
return check_status(pid);
|
||||
return wait_for_process(pid);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user