From: Miroslav Lichvar Date: Mon, 18 Nov 2019 17:07:16 +0000 (+0100) Subject: socket: add support for blocking sockets X-Git-Tag: 4.0-pre1~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0dba2b9689dff6fb5d88cfd13817896d1140d8dd;p=thirdparty%2Fchrony.git socket: add support for blocking sockets Add a flag to open a blocking socket. The default stays non-blocking. --- diff --git a/socket.c b/socket.c index d7edf7da..7126fab9 100644 --- a/socket.c +++ b/socket.c @@ -83,7 +83,7 @@ struct MessageHeader { static int initialised; /* Flags supported by socket() */ -static int socket_flags; +static int supported_socket_flags; /* Arrays of Message and MessageHeader */ static ARR_Instance recv_messages; @@ -182,34 +182,58 @@ set_socket_nonblock(int sock_fd) /* ================================================== */ static int -open_socket(int domain, int type, int flags) +get_open_flags(int flags) { - int sock_fd; + int r = supported_socket_flags; - sock_fd = socket(domain, type | socket_flags, 0); +#ifdef SOCK_NONBLOCK + if (flags & SCK_FLAG_BLOCK) + r &= ~SOCK_NONBLOCK; +#endif - if (sock_fd < 0) { - DEBUG_LOG("Could not open %s socket : %s", - domain_to_string(domain), strerror(errno)); - return INVALID_SOCK_FD; - } + return r; +} + +/* ================================================== */ +static int +set_socket_flags(int sock_fd, int flags) +{ /* Close the socket automatically on exec */ if ( #ifdef SOCK_CLOEXEC - (socket_flags & SOCK_CLOEXEC) == 0 && + (supported_socket_flags & SOCK_CLOEXEC) == 0 && #endif - !UTI_FdSetCloexec(sock_fd)) { - close(sock_fd); - return INVALID_SOCK_FD; - } + !UTI_FdSetCloexec(sock_fd)) + return 0; /* Enable non-blocking mode */ - if ( + if ((flags & SCK_FLAG_BLOCK) == 0 && #ifdef SOCK_NONBLOCK - (socket_flags & SOCK_NONBLOCK) == 0 && + (supported_socket_flags & SOCK_NONBLOCK) == 0 && #endif - !set_socket_nonblock(sock_fd)) { + !set_socket_nonblock(sock_fd)) + return 0; + + return 1; +} + +/* ================================================== */ + +static int +open_socket(int domain, int type, int flags) +{ + int sock_fd; + + sock_fd = socket(domain, type | get_open_flags(flags), 0); + + if (sock_fd < 0) { + DEBUG_LOG("Could not open %s socket : %s", + domain_to_string(domain), strerror(errno)); + return INVALID_SOCK_FD; + } + + if (!set_socket_flags(sock_fd, flags)) { close(sock_fd); return INVALID_SOCK_FD; } @@ -1025,14 +1049,14 @@ SCK_Initialise(void) priv_bind_function = NULL; - socket_flags = 0; + supported_socket_flags = 0; #ifdef SOCK_CLOEXEC if (check_socket_flag(SOCK_CLOEXEC, FD_CLOEXEC, 0)) - socket_flags |= SOCK_CLOEXEC; + supported_socket_flags |= SOCK_CLOEXEC; #endif #ifdef SOCK_NONBLOCK if (check_socket_flag(SOCK_NONBLOCK, 0, O_NONBLOCK)) - socket_flags |= SOCK_NONBLOCK; + supported_socket_flags |= SOCK_NONBLOCK; #endif initialised = 1; diff --git a/socket.h b/socket.h index f28329e5..47b9b5b5 100644 --- a/socket.h +++ b/socket.h @@ -31,6 +31,7 @@ #include "addressing.h" /* Flags for opening sockets */ +#define SCK_FLAG_BLOCK 1 #define SCK_FLAG_BROADCAST 2 #define SCK_FLAG_RX_DEST_ADDR 4 #define SCK_FLAG_ALL_PERMISSIONS 8