mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
socket: check result of SO_NOSIGPIPE
New define USE_SO_NOSIGPIPE in curl_setup.h, for now set whenever SO_NOSIGPIPE is defined. Maybe overridden in the future on systems where this does not work. With USE_SO_NOSIGPIPE defined, set SO_NOSIGPIPE on all sockets created by libcurl and fail the creation when setsockopt() fails. Closes #20370
This commit is contained in:
parent
0bef137fbd
commit
3dd7f5890f
@ -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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user