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);
}