From: Alan T. DeKok Date: Wed, 22 Apr 2020 13:34:24 +0000 (-0400) Subject: add input_fd functionality to async exec-wait X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b6ff33dad0b656ff968f91d7f722f7b33b996a2;p=thirdparty%2Ffreeradius-server.git add input_fd functionality to async exec-wait --- diff --git a/src/lib/server/exec.c b/src/lib/server/exec.c index 0b24d1f8d2e..270436fe82e 100644 --- a/src/lib/server/exec.c +++ b/src/lib/server/exec.c @@ -757,7 +757,8 @@ int fr_exec_nowait(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pairs) * @param vb as returned by xlat_frame_eval() * @param env_pairs VPs to put into into the environment. May be NULL. * @param[out] pid_p The PID of the child - * @param[out] fd_p The stdout FD of the child + * @param[out] input_fd The stdin FD of the child + * @param[out] output_fd The stdout FD of the child * @return * - <0 on error * - 0 on success @@ -766,13 +767,14 @@ int fr_exec_nowait(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pairs) * would allow finer-grained control over the attributes to put into * the environment. */ -int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pairs, pid_t *pid_p, int *fd_p) +int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd) { int argc; char **envp; char **argv; pid_t pid; fr_value_box_t *first; + int to_child[2] = {-1, -1}; int from_child[2] = {-1, -1}; /* @@ -810,8 +812,19 @@ int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pai for (i = 0; i < argc; i++) RDEBUG3("arg[%d] %s", i, argv[i]); } - if (fd_p) { + if (input_fd) { + if (pipe(to_child) < 0) { + fr_strerror_printf("Failed opening pipe to read to child - %s", fr_strerror()); + return -1; + } + } + + if (output_fd) { if (pipe(from_child) < 0) { + if (input_fd) { + close(to_child[0]); + close(to_child[1]); + } fr_strerror_printf("Failed opening pipe to read from child - %s", fr_strerror()); return -1; } @@ -823,9 +836,7 @@ int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pai * The child never returns from calling fr_exec_child(); */ if (pid == 0) { - int unused[2] = {-1, -1}; - - fr_exec_child(request, argv, envp, true, NULL, fd_p, unused, from_child); + fr_exec_child(request, argv, envp, true, input_fd, output_fd, to_child, from_child); } /* @@ -835,7 +846,11 @@ int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pai if (pid < 0) { ERROR("Couldn't fork %s: %s", argv[0], fr_syserror(errno)); - if (fd_p) { + if (input_fd) { + close(to_child[0]); + close(to_child[1]); + } + if (output_fd) { close(from_child[0]); close(from_child[1]); } @@ -849,9 +864,14 @@ int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pai */ *pid_p = pid; - if (fd_p) { - *fd_p = from_child[0]; - fr_nonblock(*fd_p); + if (input_fd) { + *input_fd = to_child[1]; + close(from_child[0]); + } + + if (output_fd) { + *output_fd = from_child[0]; + fr_nonblock(*output_fd); close(from_child[1]); } diff --git a/src/lib/server/exec.h b/src/lib/server/exec.h index b52328cbae9..10556063713 100644 --- a/src/lib/server/exec.h +++ b/src/lib/server/exec.h @@ -61,7 +61,7 @@ int radius_exec_program(TALLOC_CTX *ctx, char *out, size_t outlen, VALUE_PAIR ** int fr_exec_nowait(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pairs); -int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pairs, pid_t *pid_p, int *fd_p); +int fr_exec_wait_start(REQUEST *request, fr_value_box_t *vb, VALUE_PAIR *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd); void fr_exec_waitpid(pid_t pid); diff --git a/src/lib/unlang/tmpl.c b/src/lib/unlang/tmpl.c index e7a2dbe949e..a3c1a24ebd4 100644 --- a/src/lib/unlang/tmpl.c +++ b/src/lib/unlang/tmpl.c @@ -341,7 +341,7 @@ static unlang_action_t unlang_tmpl_exec_wait_resume(REQUEST *request, rlm_rcode_ state->fd = -1; if (state->out) fd_p = &state->fd; - if (fr_exec_wait_start(request, state->box, NULL, &pid, fd_p) < 0) { + if (fr_exec_wait_start(request, state->box, NULL, &pid, NULL, fd_p) < 0) { REDEBUG("Failed executing program - %s", fr_strerror()); fail: *presult = RLM_MODULE_FAIL;