mirror of
https://github.com/darlinghq/xcbuild.git
synced 2025-02-21 17:00:49 +00:00
Get stdout/stderr of launched task with pipe.
This commit is contained in:
parent
2bc4616959
commit
0d63ceb478
@ -10,9 +10,13 @@
|
||||
#include <process/DefaultLauncher.h>
|
||||
#include <libutil/Filesystem.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// In most cases, size of pipe will be greater than one page,
|
||||
#define PIPE_BUFFER_SIZE 4096
|
||||
|
||||
using process::DefaultLauncher;
|
||||
using libutil::Filesystem;
|
||||
|
||||
@ -71,6 +75,14 @@ launch(Filesystem *filesystem, Context const *context)
|
||||
uid_t uid = context->userID();
|
||||
gid_t gid = context->groupID();
|
||||
|
||||
/* Setup parent-child stdout/stderr pipe. */
|
||||
int pfd[2];
|
||||
bool pipe_setup_success = true;
|
||||
if (pipe(pfd) == -1) {
|
||||
::perror("pipe");
|
||||
pipe_setup_success = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fork new process.
|
||||
*/
|
||||
@ -80,6 +92,24 @@ launch(Filesystem *filesystem, Context const *context)
|
||||
return ext::nullopt;
|
||||
} else if (pid == 0) {
|
||||
/* Fork succeeded, new process. */
|
||||
if (pipe_setup_success) {
|
||||
/* Setup pipe to parent, redirecting both stdout and stderr */
|
||||
dup2(pfd[1], STDOUT_FILENO);
|
||||
dup2(pfd[1], STDERR_FILENO);
|
||||
close(pfd[0]);
|
||||
close(pfd[1]);
|
||||
} else {
|
||||
/* No parent-child pipe setup, just ignore outputs from child */
|
||||
int nullfd = open("/dev/null", O_WRONLY);
|
||||
if (nullfd == -1) {
|
||||
::perror("open");
|
||||
::_exit(1);
|
||||
}
|
||||
dup2(nullfd, STDOUT_FILENO);
|
||||
dup2(nullfd, STDERR_FILENO);
|
||||
close(nullfd);
|
||||
}
|
||||
|
||||
if (::chdir(cDirectory) == -1) {
|
||||
::perror("chdir");
|
||||
::_exit(1);
|
||||
@ -101,6 +131,24 @@ launch(Filesystem *filesystem, Context const *context)
|
||||
return ext::nullopt;
|
||||
} else {
|
||||
/* Fork succeeded, existing process. */
|
||||
if (pipe_setup_success) {
|
||||
close(pfd[1]);
|
||||
/* Read child's stdout/stderr through pipe, and output stdout */
|
||||
while (true) {
|
||||
char pin[PIPE_BUFFER_SIZE];
|
||||
int readlen = read(pfd[0], &pin, sizeof(pin));
|
||||
if (readlen > 0) {
|
||||
fwrite(pin, readlen, 1, stdout);
|
||||
} else {
|
||||
if (readlen != 0) {
|
||||
::perror("read");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(pfd[0]);
|
||||
}
|
||||
|
||||
int status;
|
||||
::waitpid(pid, &status, 0);
|
||||
return WEXITSTATUS(status);
|
||||
|
Loading…
x
Reference in New Issue
Block a user