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 a30cdaf84cb6387f8389c07b58501e9d4c633885
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Nov 2 11:15:09 2026 +0100

    system/fastboot: Do not die of SIGPIPE when a TCP client closes.
    
    The TCP transport writes the responses to the client socket with
    write().  When the client closed the connection, the write 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
    fastbootd.
    
    Send to the TCP client with send() and MSG_NOSIGNAL, also for the reply
    to the handshake.  The error ends only the connection, as before.  The
    USB and serial transports do not change.  MSG_NOSIGNAL is used instead
    of ignoring SIGPIPE, so that "oem shell" commands keep the default
    action.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 system/fastboot/fastboot.c | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/system/fastboot/fastboot.c b/system/fastboot/fastboot.c
index 47cbf99f7..0d47c2d88 100644
--- a/system/fastboot/fastboot.c
+++ b/system/fastboot/fastboot.c
@@ -195,6 +195,7 @@ struct fastboot_cmd_s
 };
 
 typedef void (*memdump_print_t)(FAR void *, FAR const char *);
+typedef int (*fastboot_write_t)(int, FAR const void *, size_t);
 
 /****************************************************************************
  * Private Function Prototypes
@@ -1347,7 +1348,8 @@ static ssize_t fastboot_read_all(int fd, FAR void *buf, 
size_t len)
 
 static ssize_t fastboot_framed_read(FAR struct fastboot_ctx_s *ctx,
                                     int fd, FAR void *buf, size_t len,
-                                    bool detect_handshake)
+                                    bool detect_handshake,
+                                    fastboot_write_t writefn)
 {
   union
     {
@@ -1370,8 +1372,8 @@ static ssize_t fastboot_framed_read(FAR struct 
fastboot_ctx_s *ctx,
           if (memcmp(u.handshake, FASTBOOT_TCP_HANDSHAKE,
                      FASTBOOT_TCP_HANDSHAKE_LEN) == 0)
             {
-              fastboot_write(fd, FASTBOOT_TCP_HANDSHAKE,
-                             FASTBOOT_TCP_HANDSHAKE_LEN);
+              writefn(fd, FASTBOOT_TCP_HANDSHAKE,
+                      FASTBOOT_TCP_HANDSHAKE_LEN);
               continue;
             }
 
@@ -1456,6 +1458,26 @@ error:
   return -errno;
 }
 
+static int fastboot_tcp_send(int fd, FAR const void *buf, size_t len)
+{
+  FAR const char *data = buf;
+
+  while (len > 0)
+    {
+      ssize_t r = send(fd, data, len, MSG_NOSIGNAL);
+
+      if (r < 0)
+        {
+          return -errno;
+        }
+
+      data += r;
+      len -= r;
+    }
+
+  return OK;
+}
+
 static void fastboot_tcp_disconn(FAR struct fastboot_ctx_s *ctx)
 {
   close(ctx->tran_fd[1]);
@@ -1482,10 +1504,12 @@ static ssize_t fastboot_tcp_read(FAR struct 
fastboot_ctx_s *ctx,
           return -errno;
         }
 
-      return fastboot_framed_read(ctx, ctx->tran_fd[1], buf, len, true);
+      return fastboot_framed_read(ctx, ctx->tran_fd[1], buf, len, true,
+                                  fastboot_tcp_send);
     }
 
-  nread = fastboot_framed_read(ctx, ctx->tran_fd[1], buf, len, false);
+  nread = fastboot_framed_read(ctx, ctx->tran_fd[1], buf, len, false,
+                               fastboot_tcp_send);
   if (nread <= 0)
     {
       fastboot_tcp_disconn(ctx);
@@ -1500,13 +1524,13 @@ static int fastboot_tcp_write(FAR struct fastboot_ctx_s 
*ctx,
   uint64_t data_size = htobe64(len);
   int ret;
 
-  ret = fastboot_write(ctx->tran_fd[1], &data_size, sizeof(data_size));
+  ret = fastboot_tcp_send(ctx->tran_fd[1], &data_size, sizeof(data_size));
   if (ret < 0)
     {
       return ret;
     }
 
-  return fastboot_write(ctx->tran_fd[1], buf, len);
+  return fastboot_tcp_send(ctx->tran_fd[1], buf, len);
 }
 #endif
 
@@ -1553,7 +1577,8 @@ static void fastboot_serial_deinit(FAR struct 
fastboot_ctx_s *ctx)
 static ssize_t fastboot_serial_read(FAR struct fastboot_ctx_s *ctx,
                                     FAR void *buf, size_t len)
 {
-  return fastboot_framed_read(ctx, ctx->tran_fd[0], buf, len, true);
+  return fastboot_framed_read(ctx, ctx->tran_fd[0], buf, len, true,
+                              fastboot_write);
 }
 
 static int fastboot_serial_write(FAR struct fastboot_ctx_s *ctx,

Reply via email to