Implement MSG_NOSIGNAL

* Part of latest POSIX specification, this prevents send() on a closed
socket to raise a SIGPIPE signal (but EPIPE is returned).
This commit is contained in:
Adrien Destugues
2015-06-10 17:39:53 +02:00
parent de4adb68a7
commit 4b2d018be4
2 changed files with 6 additions and 4 deletions
+1
View File
@@ -121,6 +121,7 @@ struct msghdr {
#define MSG_BCAST 0x0100 /* this message rec'd as broadcast */ #define MSG_BCAST 0x0100 /* this message rec'd as broadcast */
#define MSG_MCAST 0x0200 /* this message rec'd as multicast */ #define MSG_MCAST 0x0200 /* this message rec'd as multicast */
#define MSG_EOF 0x0400 /* data completes connection */ #define MSG_EOF 0x0400 /* data completes connection */
#define MSG_NOSIGNAL 0x0800 /* don't raise SIGPIPE if socket is closed */
struct cmsghdr { struct cmsghdr {
socklen_t cmsg_len; socklen_t cmsg_len;
@@ -785,8 +785,10 @@ TCPEndpoint::SendData(net_buffer *buffer)
MutexLocker lock(fLock); MutexLocker lock(fLock);
TRACE("SendData(buffer %p, size %lu, flags %lx) [total %lu bytes, has %lu]", TRACE("SendData(buffer %p, size %lu, flags %lx) [total %lu bytes, has %lu]",
buffer, buffer->size, buffer->flags, fSendQueue.Size(), buffer, buffer->size, buffer->flags, fSendQueue.Size(),
fSendQueue.Free()); fSendQueue.Free());
uint32 flags = buffer->flags;
if (fState == CLOSED) if (fState == CLOSED)
return ENOTCONN; return ENOTCONN;
@@ -794,12 +796,11 @@ TCPEndpoint::SendData(net_buffer *buffer)
return EDESTADDRREQ; return EDESTADDRREQ;
if (!is_writable(fState) && !is_establishing(fState)) { if (!is_writable(fState) && !is_establishing(fState)) {
// we only send signals when called from userland // we only send signals when called from userland
if (gStackModule->is_syscall()) if (gStackModule->is_syscall() && (flags & MSG_NOSIGNAL != 0))
send_signal(find_thread(NULL), SIGPIPE); send_signal(find_thread(NULL), SIGPIPE);
return EPIPE; return EPIPE;
} }
uint32 flags = buffer->flags;
size_t left = buffer->size; size_t left = buffer->size;
bigtime_t timeout = absolute_timeout(socket->send.timeout); bigtime_t timeout = absolute_timeout(socket->send.timeout);