1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

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>
This commit is contained in:
Amitay Isaacs 2017-05-06 02:47:00 +10:00 committed by Martin Schwenke
parent 15367ce4b4
commit 16c188c7f8
5 changed files with 52 additions and 20 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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);