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
|
128- is 128 + signal that killed subprocess
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
int
|
||||||
check_status(pid_t pid)
|
wait_for_process(pid_t pid)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
int status;
|
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
|
int
|
||||||
simple_execvp(const char *file, char *const args[])
|
simple_execvp(const char *file, char *const args[])
|
||||||
{
|
{
|
||||||
@@ -93,7 +181,7 @@ simple_execvp(const char *file, char *const args[])
|
|||||||
execvp(file, args);
|
execvp(file, args);
|
||||||
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
||||||
default:
|
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);
|
execve(file, args, envp);
|
||||||
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC);
|
||||||
default:
|
default:
|
||||||
return check_status(pid);
|
return wait_for_process(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user