This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 5d41aae5256b0c61e45aa4b663442b9aed3a1c53
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Nov 2 11:17:29 2026 +0100

    netutils/thttpd: Do not die of SIGPIPE when a client closes.
    
    thttpd writes to the client socket with write() in the server task, in
    the CGI task and with stdio in the directory indexing task.  When the
    client closed the connection, a write to it fails with EPIPE.  A write
    to a stream socket whose peer is gone also raises SIGPIPE, and with
    CONFIG_SIG_SIGPIPE_ACTION the default action ends the task: the server
    stops for all clients, or a CGI task stops before its clean-up.
    
    Ignore SIGPIPE in the three tasks, as upstream thttpd does in main().
    task_create() gives each task the default action, so each task sets it.
    The CGI task sets it after exec(), so the CGI program keeps the default
    action.  The failed write ends only the connection.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 netutils/thttpd/libhttpd.c   | 4 ++++
 netutils/thttpd/thttpd.c     | 8 ++++++++
 netutils/thttpd/thttpd_cgi.c | 6 ++++++
 3 files changed, 18 insertions(+)

diff --git a/netutils/thttpd/libhttpd.c b/netutils/thttpd/libhttpd.c
index 019118038..4292fda04 100644
--- a/netutils/thttpd/libhttpd.c
+++ b/netutils/thttpd/libhttpd.c
@@ -1623,6 +1623,10 @@ static void ls_child(int argc, char **argv)
   char *timestr;
   int i;
 
+#ifdef CONFIG_ENABLE_ALL_SIGNALS
+  signal(SIGPIPE, SIG_IGN);
+#endif
+
   /* Compiler was warning that dirp was not initialised and it wasn't.
    * But whether this is correct or not I am not sure.
    */
diff --git a/netutils/thttpd/thttpd.c b/netutils/thttpd/thttpd.c
index e0e59d68c..5558e2f15 100644
--- a/netutils/thttpd/thttpd.c
+++ b/netutils/thttpd/thttpd.c
@@ -678,6 +678,14 @@ int thttpd_main(int argc, char **argv)
 
   ninfo("THTTPD started\n");
 
+#ifdef CONFIG_ENABLE_ALL_SIGNALS
+  /* Get EPIPE, not SIGPIPE, when a client closes.  The CGI and the
+   * indexing tasks set it again: task_create() gives the default action.
+   */
+
+  signal(SIGPIPE, SIG_IGN);
+#endif
+
   /* Setup host address */
 
 #ifdef CONFIG_NET_IPv6
diff --git a/netutils/thttpd/thttpd_cgi.c b/netutils/thttpd/thttpd_cgi.c
index a815c8e1f..665c5b228 100644
--- a/netutils/thttpd/thttpd_cgi.c
+++ b/netutils/thttpd/thttpd_cgi.c
@@ -897,6 +897,12 @@ static int cgi_child(int argc, char **argv)
       goto errout_with_watch;
     }
 
+#ifdef CONFIG_ENABLE_ALL_SIGNALS
+  /* After exec(), so that the CGI program keeps the default action */
+
+  signal(SIGPIPE, SIG_IGN);
+#endif
+
   /* Schedule a kill for the child task in case it runs too long. */
 
 #if CONFIG_THTTPD_CGI_TIMELIMIT > 0

Reply via email to