From 441a729049a038f0b93e5ee1ab4a0d63f9a2181b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 6 Feb 2014 14:18:37 +0000 Subject: [PATCH] Add set_sock_nonblock() and set_fd_cloexec() compat functions The latter does nothing on Windows, and the former is *only* for sockets. Which means that it's probably broken where we're using it on pipes, but we'll deal with that later... Signed-off-by: David Woodhouse --- dtls.c | 4 ++-- library.c | 3 +-- openconnect-internal.h | 19 +++++++++++++++++++ ssl.c | 6 +++--- tun.c | 4 ++-- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/dtls.c b/dtls.c index 53e03d1e..baef9133 100644 --- a/dtls.c +++ b/dtls.c @@ -547,8 +547,8 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) return -EINVAL; } - fcntl(dtls_fd, F_SETFD, FD_CLOEXEC); - fcntl(dtls_fd, F_SETFL, fcntl(dtls_fd, F_GETFL) | O_NONBLOCK); + set_fd_cloexec(dtls_fd); + set_sock_nonblock(dtls_fd); ret = start_dtls_handshake(vpninfo, dtls_fd); if (ret) { diff --git a/library.c b/library.c index fa9007e4..940f3865 100644 --- a/library.c +++ b/library.c @@ -379,8 +379,7 @@ int openconnect_setup_cmd_pipe(struct openconnect_info *vpninfo) if (pipe(pipefd) < 0) return -EIO; - if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) || - fcntl(pipefd[1], F_SETFL, O_NONBLOCK)) { + if (set_sock_nonblock(pipefd[0]) || set_sock_nonblock(pipefd[1])) { close(pipefd[0]); close(pipefd[1]); return -EIO; diff --git a/openconnect-internal.h b/openconnect-internal.h index 3e9f427c..d9a8e27c 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -67,6 +67,7 @@ #include #include #include +#include #endif #ifdef LIBPROXY_HDR @@ -369,6 +370,24 @@ void openconnect__unsetenv(const char *name); int openconnect__inet_aton(const char *cp, struct in_addr *addr); #endif +static inline int set_sock_nonblock(int fd) +{ +#ifdef _WIN32 + unsigned long mode = 0; + return ioctlsocket(fd, FIONBIO, &mode); +#else + return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); +#endif +} +static inline int set_fd_cloexec(int fd) +{ +#ifdef _WIN32 + return 0; /* Windows has O_INHERIT but... */ +#else + return fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif +} + #ifdef _WIN32 #define pipe(fds) _pipe(fds, 4096, O_BINARY) #define neterrno openconnect__win32_neterrno diff --git a/ssl.c b/ssl.c index 55d27b63..b0316656 100644 --- a/ssl.c +++ b/ssl.c @@ -62,7 +62,7 @@ static int cancellable_connect(struct openconnect_info *vpninfo, int sockfd, fd_set wr_set, rd_set; int maxfd = sockfd; - fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK); + set_sock_nonblock(sockfd); if (vpninfo->protect_socket) vpninfo->protect_socket(vpninfo->cbdata, sockfd); @@ -105,7 +105,7 @@ int connect_https_socket(struct openconnect_info *vpninfo) ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP); if (ssl_sock < 0) goto reconn_err; - fcntl(ssl_sock, F_SETFD, fcntl(ssl_sock, F_GETFD) | FD_CLOEXEC); + set_fd_cloexec(ssl_sock); } if (cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen)) { reconn_err: @@ -234,7 +234,7 @@ int connect_https_socket(struct openconnect_info *vpninfo) rp->ai_protocol); if (ssl_sock < 0) continue; - fcntl(ssl_sock, F_SETFD, fcntl(ssl_sock, F_GETFD) | FD_CLOEXEC); + set_fd_cloexec(ssl_sock); if (cancellable_connect(vpninfo, ssl_sock, rp->ai_addr, rp->ai_addrlen) >= 0) { /* Store the peer address we actually used, so that DTLS can use it again later */ diff --git a/tun.c b/tun.c index 218dd111..c213b89c 100644 --- a/tun.c +++ b/tun.c @@ -633,7 +633,7 @@ static int os_setup_tun(struct openconnect_info *vpninfo) int openconnect_setup_tun_fd(struct openconnect_info *vpninfo, int tun_fd) { - fcntl(tun_fd, F_SETFD, FD_CLOEXEC); + set_fd_cloexec(tun_fd); if (vpninfo->tun_fd != -1) FD_CLR(vpninfo->tun_fd, &vpninfo->select_rfds); @@ -644,7 +644,7 @@ int openconnect_setup_tun_fd(struct openconnect_info *vpninfo, int tun_fd) FD_SET(tun_fd, &vpninfo->select_rfds); - fcntl(vpninfo->tun_fd, F_SETFL, fcntl(vpninfo->tun_fd, F_GETFL) | O_NONBLOCK); + set_sock_nonblock(tun_fd); return 0; }