diff --git a/lib/cf-socket.c b/lib/cf-socket.c index f608fbe0ba..9554b4904a 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -1234,12 +1234,25 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf, #endif #ifndef SOCK_NONBLOCK - /* set socket non-blocking */ - (void)curlx_nonblock(ctx->sock, TRUE); + /* Set socket non-blocking, must be a non-blocking socket for + * a non-blocking connect. */ + error = curlx_nonblock(ctx->sock, TRUE); + if(error < 0) { + result = CURLE_UNSUPPORTED_PROTOCOL; + ctx->error = SOCKERRNO; + goto out; + } #else - if(data->set.fopensocket) - /* set socket non-blocking */ - (void)curlx_nonblock(ctx->sock, TRUE); + if(data->set.fopensocket) { + /* Set socket non-blocking, must be a non-blocking socket for + * a non-blocking connect. */ + error = curlx_nonblock(ctx->sock, TRUE); + if(error < 0) { + result = CURLE_UNSUPPORTED_PROTOCOL; + ctx->error = SOCKERRNO; + goto out; + } + } #endif ctx->sock_connected = (ctx->addr.socktype != SOCK_DGRAM); out: diff --git a/lib/nonblock.c b/lib/nonblock.c index 4902fce111..5e7db68f03 100644 --- a/lib/nonblock.c +++ b/lib/nonblock.c @@ -50,9 +50,18 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ /* most recent unix versions */ int flags; flags = sfcntl(sockfd, F_GETFL, 0); + if(flags < 0) + return -1; + /* Check if the current file status flags have already satisfied + * the request, if so, it's no need to call fcntl() to replicate it. + */ + if(!!(flags & O_NONBLOCK) == !!nonblock) + return 0; if(nonblock) - return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK); - return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); + flags |= O_NONBLOCK; + else + flags &= ~O_NONBLOCK; + return sfcntl(sockfd, F_SETFL, flags); #elif defined(HAVE_IOCTL_FIONBIO)