From 65118e8d6f09330d11a53498cbe4fdf2b928c8c8 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Thu, 25 Jun 2026 16:00:10 +0800 Subject: [PATCH 1/2] netutils/rexec: initialize ret to avoid maybe-uninitialized When the relay loop exits early without entering any branch, ret would be returned uninitialized, tripping -Werror=maybe-uninitialized. Initialize it to 0. Assisted-by: GitHubCopilot:claude-4.8-opus Signed-off-by: wangjianyu3 --- netutils/rexec/rexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netutils/rexec/rexec.c b/netutils/rexec/rexec.c index 01c8000bf5d..519790c4ab5 100644 --- a/netutils/rexec/rexec.c +++ b/netutils/rexec/rexec.c @@ -87,7 +87,7 @@ static int do_rexec(FAR struct rexec_arg_s *arg) char buffer[REXEC_BUFSIZE]; struct pollfd fds[2]; int sock; - int ret; + int ret = 0; sock = rexec_af(&arg->host, htons(arg->port), arg->user, arg->password, arg->command, From df7145c5c4d678ed13bb1dc6e2b66a6891cacd75 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Thu, 25 Jun 2026 16:00:10 +0800 Subject: [PATCH 2/2] netutils/rexecd: use dpopen() instead of popen() to get raw fd popen() now returns a fopencookie-backed FILE* whose fileno() yields the cookie pointer rather than a real descriptor, so poll() silently ignores the negative fd and the relay loop blocks forever waiting for command completion. See https://github.com/apache/nuttx-apps/pull/3511 Use dpopen()/dpclose() to obtain the raw bidirectional socket descriptor directly, restoring the EOF/POLLHUP command-completion signal. Assisted-by: GitHubCopilot:claude-4.8-opus Signed-off-by: wangjianyu3 --- netutils/rexecd/rexecd.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/netutils/rexecd/rexecd.c b/netutils/rexecd/rexecd.c index 6c238d58668..13864a8419c 100644 --- a/netutils/rexecd/rexecd.c +++ b/netutils/rexecd/rexecd.c @@ -25,9 +25,11 @@ ****************************************************************************/ #include +#include #include #include #include +#include #include #include #include @@ -84,7 +86,7 @@ static FAR void *doit(pthread_addr_t pvarg) { char buf[REXECD_BUFSIZE]; struct pollfd fds[2]; - FAR FILE *fp; + pid_t pid; int sock = (long)pvarg; int ret; @@ -97,18 +99,18 @@ static FAR void *doit(pthread_addr_t pvarg) /* we need to read command */ getstr(sock, buf); - fp = popen(buf, "r+"); - if (!fp) - { - goto errout; - } memset(fds, 0, sizeof(fds)); - fds[0].fd = fileno(fp); fds[0].events = POLLIN; fds[1].fd = sock; fds[1].events = POLLIN; + fds[0].fd = dpopen(buf, O_RDWR, &pid); + if (fds[0].fd < 0) + { + goto errout; + } + while (1) { ret = poll(fds, 2, -1); @@ -119,7 +121,7 @@ static FAR void *doit(pthread_addr_t pvarg) if (fds[0].revents & POLLIN) { - ret = read(fileno(fp), buf, REXECD_BUFSIZE); + ret = read(fds[0].fd, buf, REXECD_BUFSIZE); if (ret <= 0) { break; @@ -140,7 +142,7 @@ static FAR void *doit(pthread_addr_t pvarg) break; } - ret = write(fileno(fp), buf, ret); + ret = write(fds[0].fd, buf, ret); if (ret < 0) { break; @@ -154,7 +156,7 @@ static FAR void *doit(pthread_addr_t pvarg) } } - pclose(fp); + dpclose(fds[0].fd, pid); errout: close(sock); return NULL;