Avoid SIGPIPE on OS X without MSG_NOSIGNAL
OS X does not have Linux-specific option MSG_NOSIGNAL. SIGPIPE can be avoided on OS X by using sockopt SO_NOSIGPIPE. Credits: https://noahdesu.github.io/2014/01/16/port-sendmsg.html
This commit is contained in:
parent
14acb6bbed
commit
66f2001c7b
|
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No MSG_NOSIGNAL on OS X.
|
||||||
|
* Avoid SIGPIPE by using sockopt call.
|
||||||
|
*/
|
||||||
|
#ifdef MSG_NOSIGNAL
|
||||||
|
# define AMQP_CPP_MSG_NOSIGNAL MSG_NOSIGNAL
|
||||||
|
#else
|
||||||
|
# define AMQP_CPP_MSG_NOSIGNAL 0
|
||||||
|
# ifdef SO_NOSIGPIPE
|
||||||
|
# define AMQP_CPP_USE_SO_NOSIGPIPE
|
||||||
|
# else
|
||||||
|
# error "Cannot block SIGPIPE!"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AMQP_CPP_USE_SO_NOSIGPIPE
|
||||||
|
/**
|
||||||
|
* Ignore SIGPIPE when there is no MSG_NOSIGNAL.
|
||||||
|
*/
|
||||||
|
inline void set_sockopt_nosigpipe(int socket)
|
||||||
|
{
|
||||||
|
int optval = 1;
|
||||||
|
setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include "../include/outbuffer.h"
|
#include "../include/outbuffer.h"
|
||||||
#include "../include/watchable.h"
|
#include "../include/watchable.h"
|
||||||
#include "../include/monitor.h"
|
#include "../include/monitor.h"
|
||||||
|
#include "../include/tcpdefines.h"
|
||||||
|
|
||||||
// amqp types
|
// amqp types
|
||||||
#include "../include/field.h"
|
#include "../include/field.h"
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ public:
|
||||||
if (_out) return _out.add(buffer, size);
|
if (_out) return _out.add(buffer, size);
|
||||||
|
|
||||||
// there is no buffer, send the data right away
|
// there is no buffer, send the data right away
|
||||||
auto result = ::send(_socket, buffer, size, MSG_NOSIGNAL);
|
auto result = ::send(_socket, buffer, size, AMQP_CPP_MSG_NOSIGNAL);
|
||||||
|
|
||||||
// number of bytes sent
|
// number of bytes sent
|
||||||
size_t bytes = result < 0 ? 0 : result;
|
size_t bytes = result < 0 ? 0 : result;
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ public:
|
||||||
header.msg_iovlen = index;
|
header.msg_iovlen = index;
|
||||||
|
|
||||||
// send the data
|
// send the data
|
||||||
auto result = sendmsg(socket, &header, MSG_NOSIGNAL);
|
auto result = sendmsg(socket, &header, AMQP_CPP_MSG_NOSIGNAL);
|
||||||
|
|
||||||
// skip on error, or when nothing was written
|
// skip on error, or when nothing was written
|
||||||
if (result <= 0) return total > 0 ? total : result;
|
if (result <= 0) return total > 0 ? total : result;
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,10 @@ private:
|
||||||
|
|
||||||
// set the option
|
// set the option
|
||||||
setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int));
|
setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int));
|
||||||
|
|
||||||
|
#ifdef AMQP_CPP_USE_SO_NOSIGPIPE
|
||||||
|
set_sockopt_nosigpipe(_socket);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::runtime_error &error)
|
catch (const std::runtime_error &error)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue