main: Add `stderr` option for cgi-exec to redirect stderr to stdout master
authorRichard Yu <yurichard3839@gmail.com>
Mon, 1 Sep 2025 14:27:33 +0000 (22:27 +0800)
committerRobert Marko <robimarko@gmail.com>
Thu, 11 Dec 2025 11:15:13 +0000 (12:15 +0100)
This feature is used by openwrt/luci#7920
It allows cgi processes to follow real-time output sent to stderr.

Closes #2

Signed-off-by: Richard Yu <yurichard3839@gmail.com>
Signed-off-by: Paul Donald <newtwen+github@gmail.com>
Link: https://github.com/openwrt/cgi-io/pull/3
Signed-off-by: Robert Marko <robimarko@gmail.com>
main.c

diff --git a/main.c b/main.c
index 8ca4c046d96eefe88aa8221e93814d0de7a0994c..806d7153cde28d99f1c4ab9801177adfa61d3d1b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -730,15 +730,15 @@ lookup_executable(const char *cmd)
 static int
 main_exec(int argc, char **argv)
 {
-       char *fields[] = { "sessionid", NULL, "command", NULL, "filename", NULL, "mimetype", NULL };
+       char *fields[] = { "sessionid", NULL, "command", NULL, "filename", NULL, "mimetype", NULL, "stderr", NULL };
        int i, devnull, status, fds[2];
-       bool allowed = false;
+       bool allowed = false, redir_stderr = false;
        ssize_t len = 0;
        const char *exe;
        char *p, **args;
        pid_t pid;
 
-       autochar *post = postdecode(fields, 4);
+       autochar *post = postdecode(fields, 5);
        (void) post;
 
        if (!fields[1] || !session_access(fields[1], "cgi-io", "exec", "read"))
@@ -752,6 +752,10 @@ main_exec(int argc, char **argv)
                if (!isalnum(*p) && !strchr(" .;=/-", *p))
                        return failure(400, 0, "Invalid characters in mimetype");
 
+       p = fields[9];
+       if (p && p[0] == '1' && p[1] == '\0')
+               redir_stderr = true;
+
        args = fields[3] ? parse_command(fields[3]) : NULL;
 
        if (!args)
@@ -796,7 +800,8 @@ main_exec(int argc, char **argv)
 
                if (devnull > -1) {
                        dup2(devnull, 0);
-                       dup2(devnull, 2);
+                       if (!redir_stderr)
+                               dup2(devnull, 2);
                        close(devnull);
                }
                else {
@@ -805,6 +810,8 @@ main_exec(int argc, char **argv)
                }
 
                dup2(fds[1], 1);
+               if (redir_stderr)
+                       dup2(fds[1], 2);
                close(fds[0]);
                close(fds[1]);