On 2020-08-16 15:58, Wes Hardaker wrote:
> Magnus Fromreide <ma...@lysator.liu.se> writes:
> 
>> That is a more lenient option than just dropping it so I think 'happy with
>> dropping it' covers this variant. On the other hand I usually am far from
>> the most conservative one in discussions like  this one.
> 
> I think off by default makes a lot more sense than an out-right removal.

How about restoring uClinux support with the patch below? parse_cmd() and
dup() are called before fork(). That change makes it possible to use a
regular pipe between the parent and the child, even when using vfork(). The
patch below has been tested on Linux (but not on uClinux).

Thanks,

Bart.


diff --git a/agent/mibgroup/util_funcs.c b/agent/mibgroup/util_funcs.c
index f39ea1adcd89..d42277b18f7e 100644
--- a/agent/mibgroup/util_funcs.c
+++ b/agent/mibgroup/util_funcs.c
@@ -458,53 +458,60 @@ int
 get_exec_pipes(const char *cmd, int *fdIn, int *fdOut, netsnmp_pid_t *pid)
 {
 #if defined(HAVE_EXECV)
-    int             fd[2][2];
+    int             fd[2][2], stdin_fd, stdout_fd, stderr_fd;
     char           **argv, *args;

+    argv = parse_cmd(&args, cmd);
+    if (!argv) {
+        DEBUGMSGTL(("util_funcs", "get_exec_pipes(): argv == NULL\n"));
+        return 0;
+    }
     /*
-     * Setup our pipes
+     * Setup pipes
      */
     if (pipe(fd[0]) || pipe(fd[1])) {
         setPerrorstatus("pipe");
         return 0;
     }
-    if ((*pid = fork()) == 0) { /* First handle for the child */
-        close(fd[0][1]);
-        close(fd[1][0]);
-        close(0);
-        if (dup(fd[0][0]) != 0) {
-            setPerrorstatus("dup 0");
-            return 0;
-        }
-        close(fd[0][0]);
-        close(1);
-        if (dup(fd[1][1]) != 1) {
-            setPerrorstatus("dup 1");
-            return 0;
-        }
-        close(fd[1][1]);
-
-        /*
-         * write standard output and standard error to pipe.
-         */
+    /* Save stdin, stdout and stderr */
+    stdin_fd = dup(STDIN_FILENO);
+    stdout_fd = dup(STDOUT_FILENO);
+    stderr_fd = dup(STDERR_FILENO);
+    /* Redirect stdin, stdout and stderr to the child side of the pipe */
+    if (dup2(fd[0][0], STDIN_FILENO) != 0) {
+        setPerrorstatus("dup 0");
+        return 0;
+    }
+    if (dup2(fd[1][1], STDOUT_FILENO) != 1) {
+        setPerrorstatus("dup 1");
+        return 0;
+    }
+    NETSNMP_IGNORE_RESULT(dup2(STDOUT_FILENO, STDERR_FILENO));
+#ifdef __uClinux__
+    if ((*pid = vfork()) == 0) {
+#else
+    if ((*pid = fork()) == 0) {
         /*
          * close all non-standard open file descriptors
          */
-        netsnmp_close_fds(1);
-        NETSNMP_IGNORE_RESULT(dup(1));  /* stderr */
+        netsnmp_close_fds(STDOUT_FILENO);
+#endif

-        argv = parse_cmd(&args, cmd);
-        if (!argv) {
-            DEBUGMSGTL(("util_funcs", "get_exec_pipes(): argv == NULL\n"));
-            return 0;
-        }
-        DEBUGMSGTL(("util_funcs", "get_exec_pipes(): argv[0] = %s\n", 
argv[0]));
+        /* Child process */
         execv(argv[0], argv);
         perror(argv[0]);
         free(argv);
         free(args);
-        exit(1);
+        return 1;
     } else {
+        /* Parent process. */
+        /* Restore stdin, stdout and stderr */
+        dup2(stdin_fd, STDIN_FILENO);
+        close(stdin_fd);
+        dup2(stdout_fd, STDOUT_FILENO);
+        close(stdout_fd);
+        dup2(stderr_fd, STDERR_FILENO);
+        close(stderr_fd);
         close(fd[0][0]);
         close(fd[1][1]);
         if (*pid < 0) {


_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to