socket: check result of SO_NOSIGPIPE
No binary (build failed)
—
(log yok)
| @@ -107,6 +107,11 @@ A fixed faked value to use instead of a proper random number so that functions | |
| in libcurl that are otherwise getting random outputs can be tested for what | |
| they generate. | |
| + | ## `CURL_SIGPIPE_DEBUG` |
| + | |
| + | When present, `curl` does not set `SIGPIPE` to ignore. This allows |
| + | verification that `libcurl` does not cause `SIGPIPE` to be raised. |
| + | |
| ## `CURL_SMALLREQSEND` | |
| An alternative size of HTTP data to be sent at a time only if smaller than the | |
| @@ -97,32 +97,6 @@ static void tcpnodelay(struct Curl_cfilter *cf, | |
| #endif | |
| } | |
| - | #ifdef SO_NOSIGPIPE |
| - | /* The preferred method on macOS (10.2 and later) to prevent SIGPIPEs when |
| - | sending data to a dead peer (instead of relying on the 4th argument to send |
| - | being MSG_NOSIGNAL). Possibly also existing and in use on other BSD |
| - | systems? */ |
| - | static void nosigpipe(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, |
| - | curl_socket_t sockfd) |
| - | { |
| - | int onoff = 1; |
| - | if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, |
| - | (void *)&onoff, sizeof(onoff)) < 0) { |
| - | #ifndef CURL_DISABLE_VERBOSE_STRINGS |
| - | char buffer[STRERROR_LEN]; |
| - | CURL_TRC_CF(data, cf, "Could not set SO_NOSIGPIPE: %s", |
| - | curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); |
| - | #else |
| - | (void)cf; |
| - | (void)data; |
| - | #endif |
| - | } |
| - | } |
| - | #else |
| - | #define nosigpipe(x, y, z) Curl_nop_stmt |
| - | #endif |
| - | |
| #if defined(USE_WINSOCK) || \ | |
| (defined(__sun) && !defined(TCP_KEEPIDLE)) || \ | |
| (defined(__DragonFly__) && __DragonFly_version < 500702) || \ | |
| @@ -358,6 +332,19 @@ static CURLcode socket_open(struct Curl_easy *data, | |
| return CURLE_COULDNT_CONNECT; | |
| } | |
| + | #ifdef USE_SO_NOSIGPIPE |
| + | { |
| + | int onoff = 1; |
| + | if(setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, |
| + | (void *)&onoff, sizeof(onoff)) < 0) { |
| + | failf(data, "setsockopt enable SO_NOSIGPIPE: %s", |
| + | curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); |
| + | *sockfd = CURL_SOCKET_BAD; |
| + | return CURLE_COULDNT_CONNECT; |
| + | } |
| + | } |
| + | #endif /* USE_SO_NOSIGPIPE */ |
| + | |
| #ifdef HAVE_FCNTL | |
| if(fcntl(*sockfd, F_SETFD, FD_CLOEXEC) < 0) { | |
| failf(data, "fcntl set CLOEXEC: %s", | |
| @@ -1101,8 +1088,6 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf, | |
| if(is_tcp && data->set.tcp_nodelay) | |
| tcpnodelay(cf, data, ctx->sock); | |
| - | nosigpipe(cf, data, ctx->sock); |
| - | |
| if(is_tcp && data->set.tcp_keepalive) | |
| tcpkeepalive(cf, data, ctx->sock); | |
| @@ -453,6 +453,10 @@ | |
| #define USE_EVENTFD | |
| #endif | |
| + | #ifdef SO_NOSIGPIPE |
| + | #define USE_SO_NOSIGPIPE |
| + | #endif |
| + | |
| #include <stdio.h> | |
| #include <assert.h> | |
| @@ -25,8 +25,7 @@ | |
| ***************************************************************************/ | |
| #include "curl_setup.h" | |
| - | #if defined(HAVE_SIGACTION) && \ |
| - | (defined(USE_OPENSSL) || defined(USE_MBEDTLS) || defined(USE_WOLFSSL)) |
| + | #if defined(HAVE_SIGACTION) && !defined(USE_SO_NOSIGPIPE) |
| #include <signal.h> | |
| struct Curl_sigpipe_ctx { | |
| @@ -58,8 +57,10 @@ static CURL_INLINE void sigpipe_ignore(struct Curl_easy *data, | |
| action = ig->old_pipe_act; | |
| /* ignore this signal */ | |
| action.sa_handler = SIG_IGN; | |
| + | #ifdef SA_SIGINFO |
| /* clear SA_SIGINFO flag since we are using sa_handler */ | |
| action.sa_flags &= ~SA_SIGINFO; | |
| + | #endif |
| sigaction(SIGPIPE, &action, NULL); | |
| } | |
| } | |
| @@ -85,8 +86,8 @@ static CURL_INLINE void sigpipe_apply(struct Curl_easy *data, | |
| } | |
| } | |
| - | #else |
| - | /* for systems without sigaction */ |
| + | #else /* !HAVE_SIGACTION || USE_SO_NOSIGPIPE */ |
| + | /* for systems without sigaction or where SO_NOSIGPIPE is used. */ |
| #define sigpipe_ignore(x, y) do { (void)x; (void)y; } while(0) | |
| #define sigpipe_apply(x, y) do { (void)x; (void)y; } while(0) | |
| #define sigpipe_init(x) do { (void)x; } while(0) | |
| @@ -96,6 +97,6 @@ struct Curl_sigpipe_ctx { | |
| bool dummy; | |
| }; | |
| - | #endif |
| + | #endif /* else HAVE_SIGACTION && !USE_SO_NOSIGPIPE */ |
| #endif /* HEADER_CURL_SIGPIPE_H */ | |
| @@ -172,6 +172,9 @@ int main(int argc, char *argv[]) | |
| } | |
| #if defined(HAVE_SIGNAL) && defined(SIGPIPE) | |
| + | #ifdef DEBUGBUILD |
| + | if(!curl_getenv("CURL_SIGPIPE_DEBUG")) |
| + | #endif |
| (void)signal(SIGPIPE, SIG_IGN); | |
| #endif | |