1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#include "build_db.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#define PKG_BUILD_CMD "./scripts/run_pkg_build.sh"
void package_run_build(const package_info_t* info) {
// PIPE and FORK to run install script
int pipefds[2] = {0};
if (pipe(pipefds) < 0) die("failed to pipe: %s", strerror(errno));
pid_t pid = fork();
if (pid < 0) die("failed to fork: %s", strerror(errno));
if (pid == 0) {
// child proc
// connect my stdout and stderr to the pipe
close(pipefds[0]);
dup2(pipefds[1], STDOUT_FILENO);
dup2(pipefds[1], STDERR_FILENO);
close(pipefds[1]);
// exec into install script
char* argv[] = { PKG_BUILD_CMD, info->script_path, NULL };
char* envp[] = { NULL };
execve(PKG_BUILD_CMD, argv, envp);
// what are you still doing here?
die("CHILD - execve to %s failed: %s", PKG_BUILD_CMD, strerror(errno));
} else {
// parent proc, close write end of pipe
close(pipefds[1]);
}
// read from the pipe until EOF
char buf[4096];
ssize_t bytes_read = 0;
while ((bytes_read = read(pipefds[0], buf, sizeof(buf))) > 0) {
// print build out, can log and stuff in future
printf("%.*s", (int)bytes_read, buf);
}
if (bytes_read < 0) die("failed to read from pipe: %s", strerror(errno));
close(pipefds[0]);
// reap the child to finish
int wstatus;
if (waitpid(pid, &wstatus, 0) < 0) die("waitpid failed: %s", strerror(errno));
if (WEXITSTATUS(wstatus) != 0) die("the child failed to execute install script");
}
|