diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-05-06 02:47:00 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-05-30 03:58:06 +0200 |
commit | 16c188c7f8e335e5c8c191148be2f8347020178a (patch) | |
tree | 33782cc590a919294147e741629d4ae26249a73b /ctdb | |
parent | 15367ce4b413b6d7c42b6e0a3eac1f42eeedc564 (diff) | |
download | samba-16c188c7f8e335e5c8c191148be2f8347020178a.tar.gz |
ctdb-common: Update run_proc api to re-assign stdin
This allows to pass data to a child process via stdin.
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Diffstat (limited to 'ctdb')
-rw-r--r-- | ctdb/common/run_proc.c | 13 | ||||
-rw-r--r-- | ctdb/common/run_proc.h | 3 | ||||
-rw-r--r-- | ctdb/server/ctdb_eventd.c | 4 | ||||
-rwxr-xr-x | ctdb/tests/cunit/run_proc_001.sh | 38 | ||||
-rw-r--r-- | ctdb/tests/src/run_proc_test.c | 14 |
5 files changed, 52 insertions, 20 deletions
diff --git a/ctdb/common/run_proc.c b/ctdb/common/run_proc.c index f9fee80e907..53862026bd5 100644 --- a/ctdb/common/run_proc.c +++ b/ctdb/common/run_proc.c @@ -67,7 +67,7 @@ static void proc_read_handler(struct tevent_context *ev, void *private_data); static int proc_start(struct proc_context *proc, struct tevent_context *ev, - const char *path, const char **argv) + const char *path, const char **argv, int stdin_fd) { int fd[2]; int ret; @@ -99,6 +99,13 @@ static int proc_start(struct proc_context *proc, struct tevent_context *ev, close(fd[1]); + if (stdin_fd != -1) { + ret = dup2(stdin_fd, STDIN_FILENO); + if (ret == -1) { + exit(64 + errno); + } + } + ret = setpgid(0, 0); if (ret != 0) { exit(64 + errno); @@ -382,7 +389,7 @@ struct tevent_req *run_proc_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct run_proc_context *run_ctx, const char *path, const char **argv, - struct timeval timeout) + int stdin_fd, struct timeval timeout) { struct tevent_req *req; struct run_proc_state *state; @@ -415,7 +422,7 @@ struct tevent_req *run_proc_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - ret = proc_start(state->proc, ev, path, argv); + ret = proc_start(state->proc, ev, path, argv, stdin_fd); if (ret != 0) { tevent_req_error(req, ret); return tevent_req_post(req, ev); diff --git a/ctdb/common/run_proc.h b/ctdb/common/run_proc.h index 4287347cc64..7de0c84f857 100644 --- a/ctdb/common/run_proc.h +++ b/ctdb/common/run_proc.h @@ -68,6 +68,7 @@ int run_proc_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, * @param[in] run_ctx Run_proc context * @param[in] prog The path to the executable * @param[in] argv Arguments to the executable + * @param[in] stdin_fd Assign stdin_fd as stdin for the process, -1 if not * @param[in] timeout How long to wait for execution * @return new tevent request, or NULL on failure * @@ -77,7 +78,7 @@ struct tevent_req *run_proc_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct run_proc_context *run_ctx, const char *prog, const char **argv, - struct timeval timeout); + int stdin_fd, struct timeval timeout); /** * @brief Async computation end to run an executable diff --git a/ctdb/server/ctdb_eventd.c b/ctdb/server/ctdb_eventd.c index 232711ce4e2..3542b4fb6f0 100644 --- a/ctdb/server/ctdb_eventd.c +++ b/ctdb/server/ctdb_eventd.c @@ -343,7 +343,7 @@ static struct tevent_req *run_debug_send(TALLOC_CTX *mem_ctx, debug_script, argv[1], argv[2]); subreq = run_proc_send(state, ev, ectx->run_ctx, debug_script, argv, - tevent_timeval_zero()); + -1, tevent_timeval_zero()); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -709,7 +709,7 @@ static struct tevent_req *run_event_run_script(struct tevent_req *req) path, state->argv[0], state->argv[1]); subreq = run_proc_send(state, state->ev, state->ectx->run_ctx, - path, state->argv, state->timeout); + path, state->argv, -1, state->timeout); talloc_free(path); diff --git a/ctdb/tests/cunit/run_proc_001.sh b/ctdb/tests/cunit/run_proc_001.sh index e1937a82f28..b817637e574 100755 --- a/ctdb/tests/cunit/run_proc_001.sh +++ b/ctdb/tests/cunit/run_proc_001.sh @@ -6,7 +6,7 @@ ok <<EOF Process exited with error 2 EOF -unit_test run_proc_test 0 /a/b/c +unit_test run_proc_test 0 -1 /a/b/c # Non-executable path prog=$(mktemp --tmpdir="$TEST_VAR_DIR") @@ -17,7 +17,7 @@ EOF ok <<EOF Process exited with error 13 EOF -unit_test run_proc_test 0 "$prog" +unit_test run_proc_test 0 -1 "$prog" # Executable path chmod +x "$prog" @@ -25,7 +25,7 @@ chmod +x "$prog" ok <<EOF Process exited with error 8 EOF -unit_test run_proc_test 0 "$prog" +unit_test run_proc_test 0 -1 "$prog" # Capture output cat > "$prog" <<EOF @@ -38,7 +38,7 @@ Process exited with status 0 Output = (hello ) EOF -unit_test run_proc_test 0 "$prog" +unit_test run_proc_test 0 -1 "$prog" # Specify timeout ok <<EOF @@ -46,7 +46,7 @@ Process exited with status 0 Output = (hello ) EOF -unit_test run_proc_test 5 "$prog" +unit_test run_proc_test 5 -1 "$prog" # Redirected output output=$(mktemp --tmpdir="$TEST_VAR_DIR") @@ -59,7 +59,7 @@ EOF ok <<EOF Process exited with status 0 EOF -unit_test run_proc_test 0 "$prog" +unit_test run_proc_test 0 -1 "$prog" ok <<EOF hello @@ -75,7 +75,7 @@ EOF ok <<EOF Process exited with status 1 EOF -unit_test run_proc_test 0 "$prog" +unit_test run_proc_test 0 -1 "$prog" # Exit with signal cat > "$prog" <<EOF @@ -86,7 +86,7 @@ EOF ok <<EOF Process exited with signal 15 EOF -unit_test run_proc_test 0 "$prog" +unit_test run_proc_test 0 -1 "$prog" # Exit with timeout cat > "$prog" <<EOF @@ -107,7 +107,7 @@ Child = PID Output = (Sleeping for 5 seconds ) EOF -unit_test run_proc_test 1 "$prog" +unit_test run_proc_test 1 -1 "$prog" # No zombie processes pidfile=$(mktemp --tmpdir="$TEST_VAR_DIR") @@ -122,7 +122,7 @@ ok <<EOF Process exited with error 62 Child = PID EOF -unit_test run_proc_test 1 "$prog" +unit_test run_proc_test 1 -1 "$prog" result_filter () { @@ -136,5 +136,23 @@ HEADER EOF unit_test ps -p "$pid" +# Redirect stdin +cat > "$prog" <<EOF +#!/bin/sh +cat - +EOF + +cat > "$output" <<EOF +this is sample input +EOF + +ok <<EOF +Process exited with status 0 +Output = (this is sample input +) +EOF +(unit_test run_proc_test 0 4 "$prog") 4<"$output" + rm -f "$pidfile" +rm -f "$output" rm -f "$prog" diff --git a/ctdb/tests/src/run_proc_test.c b/ctdb/tests/src/run_proc_test.c index 6db783d378f..7cfb8703e99 100644 --- a/ctdb/tests/src/run_proc_test.c +++ b/ctdb/tests/src/run_proc_test.c @@ -35,11 +35,12 @@ int main(int argc, const char **argv) char *output; struct run_proc_result result; pid_t pid; - int timeout, ret; + int timeout, ret, fd; bool status; - if (argc < 3) { - fprintf(stderr, "Usage: %s <timeout> <program> <args>\n", + if (argc < 4) { + fprintf(stderr, + "Usage: %s <timeout> <stdin-fd> <program> <args>\n", argv[0]); exit(1); } @@ -63,13 +64,18 @@ int main(int argc, const char **argv) tv = tevent_timeval_current_ofs(timeout, 0); } + fd = atoi(argv[2]); + if (fd < 0) { + fd = -1; + } + ret = run_proc_init(mem_ctx, ev, &run_ctx); if (ret != 0) { fprintf(stderr, "run_proc_init() failed, ret=%d\n", ret); exit(1); } - req = run_proc_send(mem_ctx, ev, run_ctx, argv[2], &argv[2], tv); + req = run_proc_send(mem_ctx, ev, run_ctx, argv[3], &argv[3], fd, tv); if (req == NULL) { fprintf(stderr, "run_proc_send() failed\n"); exit(1); |