]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add input_fd functionality to async exec-wait
authorAlan T. DeKok <aland@freeradius.org>
Wed, 22 Apr 2020 13:34:24 +0000 (09:34 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 22 Apr 2020 13:40:55 +0000 (09:40 -0400)
src/lib/server/exec.c
src/lib/server/exec.h
src/lib/unlang/tmpl.c

index 0b24d1f8d2e544146b8ba2c22f3dbbfbdbab8796..270436fe82e65fa501b7a4ca25d23591c9d3405d 100644 (file)
@@ -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]);
        }
 
index b52328cbae97be339d29cf3fe7c18c463da5d274..105560637132893e73aaf6bb0383164af2c7a3ab 100644 (file)
@@ -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);
 
index e7a2dbe949ef1e0c2506310b45eab3f719580a73..a3c1a24ebd4862ae51e3d1e0f801da936fbe4ebe 100644 (file)
@@ -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;