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 a94b062af302de51e2489ebc5c70b693f81a0ddf Author: Marco Casaroli <[email protected]> AuthorDate: Mon Nov 2 11:16:01 2026 +0100 industry/nxmodbus: Do not die of SIGPIPE when a TCP client closes. nxmb_tcp_send() writes the response with writev(). 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 the application that runs the Modbus server. Without the signal, nxmb_poll() returns the error, and a server loop that stops on errors other than EAGAIN (as examples/nxmbserver does) stops. Send with sendmsg() and MSG_NOSIGNAL. In server mode, a failed send closes only this client and returns -EAGAIN, as a failed read does. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- industry/nxmodbus/transport/nxmb_tcp.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/industry/nxmodbus/transport/nxmb_tcp.c b/industry/nxmodbus/transport/nxmb_tcp.c index f4b2dc940..dd1442054 100644 --- a/industry/nxmodbus/transport/nxmb_tcp.c +++ b/industry/nxmodbus/transport/nxmb_tcp.c @@ -375,6 +375,7 @@ static int nxmb_tcp_send(nxmb_handle_t ctx) FAR struct nxmb_tcp_client_s *client; uint8_t header[MBAP_FC_SIZE]; struct iovec iov[2]; + struct msghdr msg; uint16_t data_len; uint16_t total; ssize_t sent; @@ -420,7 +421,7 @@ static int nxmb_tcp_send(nxmb_handle_t ctx) data_len = ctx->adu.length - 2; - /* Emit MBAP header + PDU data via writev() to avoid a stack-side + /* Emit MBAP header + PDU data via sendmsg() to avoid a stack-side * copy. The kernel gathers both iovecs into a single TCP segment. */ @@ -431,10 +432,24 @@ static int nxmb_tcp_send(nxmb_handle_t ctx) iov[1].iov_base = ctx->adu.data; iov[1].iov_len = data_len; + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = iov; + msg.msg_iovlen = (data_len > 0) ? 2 : 1; + total = MBAP_FC_SIZE + data_len; - sent = writev(fd, iov, (data_len > 0) ? 2 : 1); + sent = sendmsg(fd, &msg, MSG_NOSIGNAL); if (sent != total) { + if (!ctx->is_client) + { + /* As for a failed read, drop only this client */ + + close(fd); + client->fd = -1; + state->active_idx = -1; + return -EAGAIN; + } + return (sent < 0) ? -errno : -EIO; }
