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>
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;
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);
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;
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);
* @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
*
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
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);
}
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);
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")
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"
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
Output = (hello
)
EOF
-unit_test run_proc_test 0 "$prog"
+unit_test run_proc_test 0 -1 "$prog"
# Specify timeout
ok <<EOF
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")
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
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
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
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")
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 ()
{
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"
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);
}
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);