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.git


The following commit(s) were added to refs/heads/master by this push:
     new 4daa8ec89ec net/socket: Raise SIGPIPE when a send finds the peer gone.
4daa8ec89ec is described below

commit 4daa8ec89ecbb2a4e0762afa73ca271bc289ad86
Author: Marco Casaroli <[email protected]>
AuthorDate: Tue Oct 20 20:34:42 2026 +0200

    net/socket: Raise SIGPIPE when a send finds the peer gone.
    
    POSIX: send(), sendto(), sendmsg() and write() on a stream socket that
    is no longer connected fail with EPIPE, and the calling thread also
    gets SIGPIPE unless MSG_NOSIGNAL is given.  NuttX returned EPIPE only,
    so SIG_SIGPIPE_ACTION and SIGPIPE handlers never saw it and MSG_NOSIGNAL
    had no effect.
    
    The new psock_sigpipe() raises SIGPIPE in the calling thread when a send
    on a SOCK_STREAM or SOCK_SEQPACKET socket returned -EPIPE and
    MSG_NOSIGNAL is not set.  sendto() (and so send()), sendmsg() and the
    write method of a socket call it.  The psock_send*() interfaces that
    the OS uses do not raise it, and kernel threads do not get it.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 fs/socket/socket.c      |  6 +++++-
 include/nuttx/net/net.h | 18 ++++++++++++++++++
 net/socket/sendmsg.c    | 33 +++++++++++++++++++++++++++++++++
 net/socket/sendto.c     |  1 +
 4 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/fs/socket/socket.c b/fs/socket/socket.c
index 50eb817eed0..e668b5d98d7 100644
--- a/fs/socket/socket.c
+++ b/fs/socket/socket.c
@@ -129,7 +129,11 @@ static ssize_t sock_file_read(FAR struct file *filep, FAR 
char *buffer,
 static ssize_t sock_file_write(FAR struct file *filep,
                                FAR const char *buffer, size_t buflen)
 {
-  return psock_send(filep->f_priv, buffer, buflen, 0);
+  ssize_t ret;
+
+  ret = psock_send(filep->f_priv, buffer, buflen, 0);
+  psock_sigpipe(filep->f_priv, ret, 0);
+  return ret;
 }
 
 static int sock_file_ioctl(FAR struct file *filep, int cmd,
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index 7ac7fac94df..2b3d3d1dd5e 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -880,6 +880,24 @@ int psock_connect(FAR struct socket *psock, FAR const 
struct sockaddr *addr,
 ssize_t psock_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg,
                       int flags);
 
+/****************************************************************************
+ * Name: psock_sigpipe
+ *
+ * Description:
+ *   Raise SIGPIPE in the calling thread when a send on a stream socket
+ *   failed with -EPIPE, unless 'flags' has MSG_NOSIGNAL.  The user
+ *   interfaces (send(), sendto(), sendmsg() and write() on a socket) call
+ *   it.  The psock_send*() interfaces do not raise SIGPIPE.
+ *
+ * Input Parameters:
+ *   psock    The socket of the send
+ *   ret      The result of the send
+ *   flags    The send flags
+ *
+ ****************************************************************************/
+
+void psock_sigpipe(FAR struct socket *psock, ssize_t ret, int flags);
+
 /****************************************************************************
  * Name: psock_recvmsg
  *
diff --git a/net/socket/sendmsg.c b/net/socket/sendmsg.c
index b20f9409327..7ead5ca11b5 100644
--- a/net/socket/sendmsg.c
+++ b/net/socket/sendmsg.c
@@ -26,12 +26,16 @@
 
 #include <nuttx/config.h>
 
+#include <sys/socket.h>
 #include <assert.h>
 #include <errno.h>
+#include <signal.h>
 
 #include <nuttx/cancelpt.h>
 #include <nuttx/fs/fs.h>
 #include <nuttx/net/net.h>
+#include <nuttx/sched.h>
+#include <nuttx/signal.h>
 
 #include "socket/socket.h"
 
@@ -97,6 +101,34 @@ ssize_t psock_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
   return psock->s_sockif->si_sendmsg(psock, msg, flags);
 }
 
+/****************************************************************************
+ * Name: psock_sigpipe
+ *
+ * Description:
+ *   Raise SIGPIPE in the calling thread when a send on a stream socket
+ *   failed with -EPIPE, unless 'flags' has MSG_NOSIGNAL.  Kernel threads do
+ *   not get the signal.
+ *
+ * Input Parameters:
+ *   psock    The socket of the send
+ *   ret      The result of the send
+ *   flags    The send flags
+ *
+ ****************************************************************************/
+
+void psock_sigpipe(FAR struct socket *psock, ssize_t ret, int flags)
+{
+#ifndef CONFIG_DISABLE_ALL_SIGNALS
+  if (ret == -EPIPE && (flags & MSG_NOSIGNAL) == 0 &&
+      (psock->s_type == SOCK_STREAM || psock->s_type == SOCK_SEQPACKET) &&
+      (nxsched_self()->flags & TCB_FLAG_TTYPE_MASK) !=
+      TCB_FLAG_TTYPE_KERNEL)
+    {
+      nxsig_tgkill(nxsched_getpid(), nxsched_gettid(), SIGPIPE);
+    }
+#endif
+}
+
 /****************************************************************************
  * Function: sendmsg
  *
@@ -159,6 +191,7 @@ ssize_t sendmsg(int sockfd, FAR const struct msghdr *msg, 
int flags)
   if (ret == OK)
     {
       ret = psock_sendmsg(psock, msg, flags);
+      psock_sigpipe(psock, ret, flags);
       file_put(filep);
     }
 
diff --git a/net/socket/sendto.c b/net/socket/sendto.c
index a1b5d1705b3..462dfb7badc 100644
--- a/net/socket/sendto.c
+++ b/net/socket/sendto.c
@@ -245,6 +245,7 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, 
int flags,
   if (ret == OK)
     {
       ret = psock_sendto(psock, buf, len, flags, to, tolen);
+      psock_sigpipe(psock, ret, flags);
       file_put(filep);
     }
 

Reply via email to