diff options
Diffstat (limited to 'snag')
| -rwxr-xr-x | snag/scripts/run_pkg_build.sh | 15 | ||||
| -rw-r--r-- | snag/src/build_db.c | 78 |
2 files changed, 81 insertions, 12 deletions
diff --git a/snag/scripts/run_pkg_build.sh b/snag/scripts/run_pkg_build.sh index d48d831..3e4b867 100755 --- a/snag/scripts/run_pkg_build.sh +++ b/snag/scripts/run_pkg_build.sh @@ -2,15 +2,28 @@ # reads a package description script and runs the configure, build, and install # steps. intended only for use by snag program +if [ -z "$1" -a -z "$2" -a -z "$3" ]; then + echo "Usage: $0 <description script>" >&2 + exit 1 +fi if [ -z "$1" ]; then echo "Usage: $0 <description script>" >&2 exit 1 fi +api_send=$1 +api_recv=$2 + +# should remove +eval "printf '\x02\x00\x00\x00' >&$api_send" +IFS= read -r data 0<&"$api_recv" +echo "data=$data" + # load the description script -. $1 +. $3 # run all install steps for package configure build install +eval "printf '\x01\x00\x00\x00' >&$api_send" diff --git a/snag/src/build_db.c b/snag/src/build_db.c index 2d0500b..01ff6bc 100644 --- a/snag/src/build_db.c +++ b/snag/src/build_db.c @@ -1,6 +1,7 @@ #include "build_db.h" #include "util.h" +#include <poll.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -10,41 +11,96 @@ #define PKG_BUILD_CMD "./scripts/run_pkg_build.sh" +#define API_MESSAGE_NONE 0 +#define API_MESSAGE_FINISHED 1 +#define API_MESSAGE_TEST 2 + void package_run_build(const package_info_t* info) { + int api_from_sh[2] = {0}; + if (pipe(api_from_sh) < 0) die("failed to open api endpoint pipe: %s", strerror(errno)); + int api_to_sh[2] = {0}; + if (pipe(api_to_sh) < 0) die("failed to open api response pipe: %s", strerror(errno)); + // PIPE and FORK to run install script - int pipefds[2] = {0}; - if (pipe(pipefds) < 0) die("failed to pipe: %s", strerror(errno)); + int child_output[2] = {0}; + if (pipe(child_output) < 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]); + close(child_output[0]); + dup2(child_output[1], STDOUT_FILENO); + dup2(child_output[1], STDERR_FILENO); + close(child_output[1]); + // close unused api pipes + close(api_from_sh[0]); + close(api_to_sh[1]); + char buf1[1024]; + snprintf(buf1, sizeof(buf1), "%d", api_from_sh[1]); + char buf2[1024]; + snprintf(buf2, sizeof(buf2), "%d", api_to_sh[0]); // exec into install script - char* argv[] = { PKG_BUILD_CMD, info->script_path, NULL }; + char* argv[] = { PKG_BUILD_CMD, buf1, buf2, 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]); + close(child_output[1]); + // close unused api pipes + close(api_from_sh[1]); + close(api_to_sh[0]); } - // read from the pipe until EOF + // all of this should be rewritten char buf[4096]; ssize_t bytes_read = 0; - while ((bytes_read = read(pipefds[0], buf, sizeof(buf))) > 0) { + struct pollfd pollfds[] = { + { .fd = api_from_sh[0], .events = POLLIN, .revents = 0 }, + { .fd = child_output[0], .events = POLLIN, .revents = 0 } + }; + bool finished = false; + while (!finished) { + if (poll(pollfds, sizeof(pollfds) / sizeof(*pollfds), 0) < 0) { + die("polling child process fds failed %s", strerror(errno)); + } + if (pollfds[1].revents == POLLIN) { + bytes_read = read(child_output[0], buf, sizeof(buf)); + if (bytes_read < 0) die("failed to read from child output: %s", strerror(errno)); + // print build out, can log and stuff in future + printf("%.*s", (int)bytes_read, buf); + } + if (pollfds[0].revents == POLLIN) { + int api_call = 0; + bytes_read = read(api_from_sh[0], &api_call, sizeof(api_call)); + if (bytes_read < 0) { + print("reading from api pipe failed: %s\n", strerror(errno)); + } + switch (api_call) { + case API_MESSAGE_FINISHED: + finished = true; + break; + case API_MESSAGE_TEST: + printf("api test\n"); + write(api_to_sh[1], "api test\n", strlen("api test\n")); + break; + case API_MESSAGE_NONE: + } + } + } + while ((bytes_read = read(child_output[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]); + close(child_output[0]); + // close api pipes + close(api_from_sh[0]); + close(api_to_sh[1]); // reap the child to finish int wstatus; |
