From 0dba2b9689dff6fb5d88cfd13817896d1140d8dd Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Mon, 18 Nov 2019 18:07:16 +0100 Subject: [PATCH] socket: add support for blocking sockets Add a flag to open a blocking socket. The default stays non-blocking. --- socket.c | 66 ++++++++++++++++++++++++++++++++++++++------------------ socket.h | 1 + 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/socket.c b/socket.c index d7edf7d..7126fab 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; @@ -181,12 +181,51 @@ set_socket_nonblock(int sock_fd) /* ================================================== */ +static int +get_open_flags(int flags) +{ + int r = supported_socket_flags; + +#ifdef SOCK_NONBLOCK + if (flags & SCK_FLAG_BLOCK) + r &= ~SOCK_NONBLOCK; +#endif + + return r; +} + +/* ================================================== */ + +static int +set_socket_flags(int sock_fd, int flags) +{ + /* Close the socket automatically on exec */ + if ( +#ifdef SOCK_CLOEXEC + (supported_socket_flags & SOCK_CLOEXEC) == 0 && +#endif + !UTI_FdSetCloexec(sock_fd)) + return 0; + + /* Enable non-blocking mode */ + if ((flags & SCK_FLAG_BLOCK) == 0 && +#ifdef SOCK_NONBLOCK + (supported_socket_flags & SOCK_NONBLOCK) == 0 && +#endif + !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 | socket_flags, 0); + sock_fd = socket(domain, type | get_open_flags(flags), 0); if (sock_fd < 0) { DEBUG_LOG("Could not open %s socket : %s", @@ -194,22 +233,7 @@ open_socket(int domain, int type, int flags) return INVALID_SOCK_FD; } - /* Close the socket automatically on exec */ - if ( -#ifdef SOCK_CLOEXEC - (socket_flags & SOCK_CLOEXEC) == 0 && -#endif - !UTI_FdSetCloexec(sock_fd)) { - close(sock_fd); - return INVALID_SOCK_FD; - } - - /* Enable non-blocking mode */ - if ( -#ifdef SOCK_NONBLOCK - (socket_flags & SOCK_NONBLOCK) == 0 && -#endif - !set_socket_nonblock(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 f28329e..47b9b5b 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