From 2451f978abd6eff6da612342b4327a1f8d3baa85 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 29 Jan 2024 16:31:06 -0500 Subject: [PATCH] compat: rename socket.h to socket.hpp `socket.h` is only included in C++ code, so make it a C++ file. This makes it possible for an upcoming patch to make it use `bt2c::Logger`. Change-Id: I42c9fd08a343357c116cf85675f36997cc1f3f2e Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/12196 Reviewed-by: Philippe Proulx Tested-by: jenkins --- src/Makefile.am | 2 +- src/compat/socket.h | 416 ------------------ src/compat/socket.hpp | 396 +++++++++++++++++ .../ctf/lttng-live/viewer-connection.hpp | 2 +- 4 files changed, 398 insertions(+), 418 deletions(-) delete mode 100644 src/compat/socket.h create mode 100644 src/compat/socket.hpp diff --git a/src/Makefile.am b/src/Makefile.am index b8eebe9f..e267ac9b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -109,7 +109,7 @@ compat_libcompat_la_SOURCES = \ compat/memstream.h \ compat/mman.c \ compat/mman.h \ - compat/socket.h \ + compat/socket.hpp \ compat/stdio.h \ compat/stdlib.h \ compat/string.h \ diff --git a/src/compat/socket.h b/src/compat/socket.h deleted file mode 100644 index 4715677e..00000000 --- a/src/compat/socket.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright (C) 2015-2017 Michael Jeanson - * Copyright (C) 2015 Mathieu Desnoyers - */ - -#ifndef _BABELTRACE_COMPAT_SOCKET_H -#define _BABELTRACE_COMPAT_SOCKET_H - -#include - -#ifdef __MINGW32__ - -#include - -#define BT_INVALID_SOCKET INVALID_SOCKET -#define BT_SOCKET_ERROR SOCKET_ERROR -#define BT_SOCKET SOCKET - -#ifndef BT_LOG_WRITE_CUR_LVL -#define BT_SOCKET_LOG_LEVEL_UNUSED_ATTR __attribute__((unused)) -#else -#define BT_SOCKET_LOG_LEVEL_UNUSED_ATTR -#endif - -static inline -int bt_socket_init(int log_level BT_SOCKET_LOG_LEVEL_UNUSED_ATTR) -{ - WORD verreq; - WSADATA wsa; - int ret; - - /* Request winsock 2.2 support */ - verreq = MAKEWORD(2, 2); - - ret = WSAStartup(verreq, &wsa); - if (ret != 0) { -#ifdef BT_LOG_WRITE_PRINTF_CUR_LVL - BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG, - "Winsock init failed with error: %d", ret); -#endif - goto end; - } - - if (LOBYTE(wsa.wVersion) != 2 || HIBYTE(wsa.wVersion) != 2) { -#ifdef BT_LOG_WRITE_CUR_LVL - BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG, - "Could not init winsock 2.2 support"); -#endif - WSACleanup(); - ret = -1; - } - -end: - return ret; -} - -static inline -int bt_socket_fini(void) -{ - return WSACleanup(); -} - -static inline -int bt_socket_send(int sockfd, const void *buf, size_t len, int flags) -{ - return send(sockfd, (const char *) buf, len, flags); -} - -static inline -int bt_socket_recv(int sockfd, void *buf, size_t len, int flags) -{ - return recv(sockfd, (char *) buf, len, flags); -} - -static inline -int bt_socket_close(int fd) -{ - return closesocket(fd); -} - -static inline -bool bt_socket_interrupted(void) -{ - /* There is no equivalent to EINTR in winsock 2.2 */ - return false; -} - -static inline -const char *bt_socket_errormsg(void) -{ - const char *errstr; - int error = WSAGetLastError(); - - switch (error) { - case WSAEINTR: - errstr = "Call interrupted"; - break; - case WSAEBADF: - errstr = "Bad file"; - break; - case WSAEACCES: - errstr = "Bad access"; - break; - case WSAEFAULT: - errstr = "Bad argument"; - break; - case WSAEINVAL: - errstr = "Invalid arguments"; - break; - case WSAEMFILE: - errstr = "Out of file descriptors"; - break; - case WSAEWOULDBLOCK: - errstr = "Call would block"; - break; - case WSAEINPROGRESS: - case WSAEALREADY: - errstr = "Blocking call in progress"; - break; - case WSAENOTSOCK: - errstr = "Descriptor is not a socket"; - break; - case WSAEDESTADDRREQ: - errstr = "Need destination address"; - break; - case WSAEMSGSIZE: - errstr = "Bad message size"; - break; - case WSAEPROTOTYPE: - errstr = "Bad protocol"; - break; - case WSAENOPROTOOPT: - errstr = "Protocol option is unsupported"; - break; - case WSAEPROTONOSUPPORT: - errstr = "Protocol is unsupported"; - break; - case WSAESOCKTNOSUPPORT: - errstr = "Socket is unsupported"; - break; - case WSAEOPNOTSUPP: - errstr = "Operation not supported"; - break; - case WSAEAFNOSUPPORT: - errstr = "Address family not supported"; - break; - case WSAEPFNOSUPPORT: - errstr = "Protocol family not supported"; - break; - case WSAEADDRINUSE: - errstr = "Address already in use"; - break; - case WSAEADDRNOTAVAIL: - errstr = "Address not available"; - break; - case WSAENETDOWN: - errstr = "Network down"; - break; - case WSAENETUNREACH: - errstr = "Network unreachable"; - break; - case WSAENETRESET: - errstr = "Network has been reset"; - break; - case WSAECONNABORTED: - errstr = "Connection was aborted"; - break; - case WSAECONNRESET: - errstr = "Connection was reset"; - break; - case WSAENOBUFS: - errstr = "No buffer space"; - break; - case WSAEISCONN: - errstr = "Socket is already connected"; - break; - case WSAENOTCONN: - errstr = "Socket is not connected"; - break; - case WSAESHUTDOWN: - errstr = "Socket has been shut down"; - break; - case WSAETOOMANYREFS: - errstr = "Too many references"; - break; - case WSAETIMEDOUT: - errstr = "Timed out"; - break; - case WSAECONNREFUSED: - errstr = "Connection refused"; - break; - case WSAELOOP: - errstr = "Loop??"; - break; - case WSAENAMETOOLONG: - errstr = "Name too long"; - break; - case WSAEHOSTDOWN: - errstr = "Host down"; - break; - case WSAEHOSTUNREACH: - errstr = "Host unreachable"; - break; - case WSAENOTEMPTY: - errstr = "Not empty"; - break; - case WSAEPROCLIM: - errstr = "Process limit reached"; - break; - case WSAEUSERS: - errstr = "Too many users"; - break; - case WSAEDQUOT: - errstr = "Bad quota"; - break; - case WSAESTALE: - errstr = "Something is stale"; - break; - case WSAEREMOTE: - errstr = "Remote error"; - break; - case WSAEDISCON: - errstr = "Disconnected"; - break; - - /* Extended Winsock errors */ - case WSASYSNOTREADY: - errstr = "Winsock library is not ready"; - break; - case WSANOTINITIALISED: - errstr = "Winsock library not initialised"; - break; - case WSAVERNOTSUPPORTED: - errstr = "Winsock version not supported"; - break; - - /* getXbyY() errors (already handled in herrmsg): - * Authoritative Answer: Host not found */ - case WSAHOST_NOT_FOUND: - errstr = "Host not found"; - break; - - /* Non-Authoritative: Host not found, or SERVERFAIL */ - case WSATRY_AGAIN: - errstr = "Host not found, try again"; - break; - - /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ - case WSANO_RECOVERY: - errstr = "Unrecoverable error in call to nameserver"; - break; - - /* Valid name, no data record of requested type */ - case WSANO_DATA: - errstr = "No data record of requested type"; - break; - - default: - errstr = "Unknown error"; - } - - return errstr; -} - -#else /* __MINGW32__ */ - -#include -#include -#include -#include -#include - -#include - -#define BT_INVALID_SOCKET -1 -#define BT_SOCKET_ERROR -1 -#define BT_SOCKET int - -static inline -int bt_socket_init(int log_level __attribute__((unused))) -{ - return 0; -} - -static inline -int bt_socket_fini(void) -{ - return 0; -} - -static inline -int bt_socket_send(int sockfd, const void *buf, size_t len, int flags) -{ - return send(sockfd, buf, len, flags); -} - -static inline -int bt_socket_recv(int sockfd, void *buf, size_t len, int flags) -{ - return recv(sockfd, buf, len, flags); -} - -static inline -int bt_socket_close(int fd) -{ - return close(fd); -} - -static inline -bool bt_socket_interrupted(void) -{ - return (errno == EINTR); -} - -static inline -const char *bt_socket_errormsg(void) -{ - return g_strerror(errno); -} -#endif - - -/* - * This wrapper is used on platforms that have no way of ignoring SIGPIPE - * during a send(). - */ - -#ifndef MSG_NOSIGNAL -# ifdef SO_NOSIGPIPE -# define MSG_NOSIGNAL SO_NOSIGPIPE -# elif defined(__MINGW32__) -# define MSG_NOSIGNAL 0 -# endif -#endif - -#if defined(MSG_NOSIGNAL) -static inline -ssize_t bt_socket_send_nosigpipe(int fd, const void *buffer, size_t size) -{ - return bt_socket_send(fd, buffer, size, MSG_NOSIGNAL); -} -#else - -#include - -static inline -ssize_t bt_socket_send_nosigpipe(int fd, const void *buffer, size_t size) -{ - ssize_t sent; - int saved_err; - sigset_t sigpipe_set, pending_set, old_set; - int sigpipe_was_pending; - - /* - * Discard the SIGPIPE from send(), not disturbing any SIGPIPE - * that might be already pending. If a bogus SIGPIPE is sent to - * the entire process concurrently by a malicious user, it may - * be simply discarded. - */ - if (sigemptyset(&pending_set)) { - return -1; - } - /* - * sigpending returns the mask of signals that are _both_ - * blocked for the thread _and_ pending for either the thread or - * the entire process. - */ - if (sigpending(&pending_set)) { - return -1; - } - sigpipe_was_pending = sigismember(&pending_set, SIGPIPE); - /* - * If sigpipe was pending, it means it was already blocked, so - * no need to block it. - */ - if (!sigpipe_was_pending) { - if (sigemptyset(&sigpipe_set)) { - return -1; - } - if (sigaddset(&sigpipe_set, SIGPIPE)) { - return -1; - } - if (pthread_sigmask(SIG_BLOCK, &sigpipe_set, &old_set)) { - return -1; - } - } - - /* Send and save errno. */ - sent = bt_socket_send(fd, buffer, size, 0); - saved_err = errno; - - if (sent == -1 && errno == EPIPE && !sigpipe_was_pending) { - struct timespec timeout = { 0, 0 }; - int ret; - - do { - ret = sigtimedwait(&sigpipe_set, NULL, - &timeout); - } while (ret == -1 && errno == EINTR); - } - if (!sigpipe_was_pending) { - if (pthread_sigmask(SIG_SETMASK, &old_set, NULL)) { - return -1; - } - } - /* Restore send() errno */ - errno = saved_err; - - return sent; -} -#endif - - -#endif /* _BABELTRACE_COMPAT_SOCKET_H */ diff --git a/src/compat/socket.hpp b/src/compat/socket.hpp new file mode 100644 index 00000000..9cb036c3 --- /dev/null +++ b/src/compat/socket.hpp @@ -0,0 +1,396 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2015-2017 Michael Jeanson + * Copyright (C) 2015 Mathieu Desnoyers + */ + +#ifndef BABELTRACE_COMPAT_SOCKET_HPP +#define BABELTRACE_COMPAT_SOCKET_HPP + +#include + +#ifdef __MINGW32__ + +# include + +# define BT_INVALID_SOCKET INVALID_SOCKET +# define BT_SOCKET_ERROR SOCKET_ERROR +# define BT_SOCKET SOCKET + +# ifndef BT_LOG_WRITE_CUR_LVL +# define BT_SOCKET_LOG_LEVEL_UNUSED_ATTR __attribute__((unused)) +# else +# define BT_SOCKET_LOG_LEVEL_UNUSED_ATTR +# endif + +static inline int bt_socket_init(int log_level BT_SOCKET_LOG_LEVEL_UNUSED_ATTR) +{ + WORD verreq; + WSADATA wsa; + int ret; + + /* Request winsock 2.2 support */ + verreq = MAKEWORD(2, 2); + + ret = WSAStartup(verreq, &wsa); + if (ret != 0) { +# ifdef BT_LOG_WRITE_PRINTF_CUR_LVL + BT_LOG_WRITE_PRINTF_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG, + "Winsock init failed with error: %d", ret); +# endif + goto end; + } + + if (LOBYTE(wsa.wVersion) != 2 || HIBYTE(wsa.wVersion) != 2) { +# ifdef BT_LOG_WRITE_CUR_LVL + BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG, + "Could not init winsock 2.2 support"); +# endif + WSACleanup(); + ret = -1; + } + +end: + return ret; +} + +static inline int bt_socket_fini(void) +{ + return WSACleanup(); +} + +static inline int bt_socket_send(int sockfd, const void *buf, size_t len, int flags) +{ + return send(sockfd, (const char *) buf, len, flags); +} + +static inline int bt_socket_recv(int sockfd, void *buf, size_t len, int flags) +{ + return recv(sockfd, (char *) buf, len, flags); +} + +static inline int bt_socket_close(int fd) +{ + return closesocket(fd); +} + +static inline bool bt_socket_interrupted(void) +{ + /* There is no equivalent to EINTR in winsock 2.2 */ + return false; +} + +static inline const char *bt_socket_errormsg(void) +{ + const char *errstr; + int error = WSAGetLastError(); + + switch (error) { + case WSAEINTR: + errstr = "Call interrupted"; + break; + case WSAEBADF: + errstr = "Bad file"; + break; + case WSAEACCES: + errstr = "Bad access"; + break; + case WSAEFAULT: + errstr = "Bad argument"; + break; + case WSAEINVAL: + errstr = "Invalid arguments"; + break; + case WSAEMFILE: + errstr = "Out of file descriptors"; + break; + case WSAEWOULDBLOCK: + errstr = "Call would block"; + break; + case WSAEINPROGRESS: + case WSAEALREADY: + errstr = "Blocking call in progress"; + break; + case WSAENOTSOCK: + errstr = "Descriptor is not a socket"; + break; + case WSAEDESTADDRREQ: + errstr = "Need destination address"; + break; + case WSAEMSGSIZE: + errstr = "Bad message size"; + break; + case WSAEPROTOTYPE: + errstr = "Bad protocol"; + break; + case WSAENOPROTOOPT: + errstr = "Protocol option is unsupported"; + break; + case WSAEPROTONOSUPPORT: + errstr = "Protocol is unsupported"; + break; + case WSAESOCKTNOSUPPORT: + errstr = "Socket is unsupported"; + break; + case WSAEOPNOTSUPP: + errstr = "Operation not supported"; + break; + case WSAEAFNOSUPPORT: + errstr = "Address family not supported"; + break; + case WSAEPFNOSUPPORT: + errstr = "Protocol family not supported"; + break; + case WSAEADDRINUSE: + errstr = "Address already in use"; + break; + case WSAEADDRNOTAVAIL: + errstr = "Address not available"; + break; + case WSAENETDOWN: + errstr = "Network down"; + break; + case WSAENETUNREACH: + errstr = "Network unreachable"; + break; + case WSAENETRESET: + errstr = "Network has been reset"; + break; + case WSAECONNABORTED: + errstr = "Connection was aborted"; + break; + case WSAECONNRESET: + errstr = "Connection was reset"; + break; + case WSAENOBUFS: + errstr = "No buffer space"; + break; + case WSAEISCONN: + errstr = "Socket is already connected"; + break; + case WSAENOTCONN: + errstr = "Socket is not connected"; + break; + case WSAESHUTDOWN: + errstr = "Socket has been shut down"; + break; + case WSAETOOMANYREFS: + errstr = "Too many references"; + break; + case WSAETIMEDOUT: + errstr = "Timed out"; + break; + case WSAECONNREFUSED: + errstr = "Connection refused"; + break; + case WSAELOOP: + errstr = "Loop??"; + break; + case WSAENAMETOOLONG: + errstr = "Name too long"; + break; + case WSAEHOSTDOWN: + errstr = "Host down"; + break; + case WSAEHOSTUNREACH: + errstr = "Host unreachable"; + break; + case WSAENOTEMPTY: + errstr = "Not empty"; + break; + case WSAEPROCLIM: + errstr = "Process limit reached"; + break; + case WSAEUSERS: + errstr = "Too many users"; + break; + case WSAEDQUOT: + errstr = "Bad quota"; + break; + case WSAESTALE: + errstr = "Something is stale"; + break; + case WSAEREMOTE: + errstr = "Remote error"; + break; + case WSAEDISCON: + errstr = "Disconnected"; + break; + + /* Extended Winsock errors */ + case WSASYSNOTREADY: + errstr = "Winsock library is not ready"; + break; + case WSANOTINITIALISED: + errstr = "Winsock library not initialised"; + break; + case WSAVERNOTSUPPORTED: + errstr = "Winsock version not supported"; + break; + + /* getXbyY() errors (already handled in herrmsg): + * Authoritative Answer: Host not found */ + case WSAHOST_NOT_FOUND: + errstr = "Host not found"; + break; + + /* Non-Authoritative: Host not found, or SERVERFAIL */ + case WSATRY_AGAIN: + errstr = "Host not found, try again"; + break; + + /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ + case WSANO_RECOVERY: + errstr = "Unrecoverable error in call to nameserver"; + break; + + /* Valid name, no data record of requested type */ + case WSANO_DATA: + errstr = "No data record of requested type"; + break; + + default: + errstr = "Unknown error"; + } + + return errstr; +} + +#else /* __MINGW32__ */ + +# include +# include +# include +# include +# include +# include + +# define BT_INVALID_SOCKET -1 +# define BT_SOCKET_ERROR -1 +# define BT_SOCKET int + +static inline int bt_socket_init(int log_level __attribute__((unused))) +{ + return 0; +} + +static inline int bt_socket_fini(void) +{ + return 0; +} + +static inline int bt_socket_send(int sockfd, const void *buf, size_t len, int flags) +{ + return send(sockfd, buf, len, flags); +} + +static inline int bt_socket_recv(int sockfd, void *buf, size_t len, int flags) +{ + return recv(sockfd, buf, len, flags); +} + +static inline int bt_socket_close(int fd) +{ + return close(fd); +} + +static inline bool bt_socket_interrupted(void) +{ + return (errno == EINTR); +} + +static inline const char *bt_socket_errormsg(void) +{ + return g_strerror(errno); +} +#endif + +/* + * This wrapper is used on platforms that have no way of ignoring SIGPIPE + * during a send(). + */ + +#ifndef MSG_NOSIGNAL +# ifdef SO_NOSIGPIPE +# define MSG_NOSIGNAL SO_NOSIGPIPE +# elif defined(__MINGW32__) +# define MSG_NOSIGNAL 0 +# endif +#endif + +#if defined(MSG_NOSIGNAL) +static inline ssize_t bt_socket_send_nosigpipe(int fd, const void *buffer, size_t size) +{ + return bt_socket_send(fd, buffer, size, MSG_NOSIGNAL); +} +#else + +# include + +static inline ssize_t bt_socket_send_nosigpipe(int fd, const void *buffer, size_t size) +{ + ssize_t sent; + int saved_err; + sigset_t sigpipe_set, pending_set, old_set; + int sigpipe_was_pending; + + /* + * Discard the SIGPIPE from send(), not disturbing any SIGPIPE + * that might be already pending. If a bogus SIGPIPE is sent to + * the entire process concurrently by a malicious user, it may + * be simply discarded. + */ + if (sigemptyset(&pending_set)) { + return -1; + } + /* + * sigpending returns the mask of signals that are _both_ + * blocked for the thread _and_ pending for either the thread or + * the entire process. + */ + if (sigpending(&pending_set)) { + return -1; + } + sigpipe_was_pending = sigismember(&pending_set, SIGPIPE); + /* + * If sigpipe was pending, it means it was already blocked, so + * no need to block it. + */ + if (!sigpipe_was_pending) { + if (sigemptyset(&sigpipe_set)) { + return -1; + } + if (sigaddset(&sigpipe_set, SIGPIPE)) { + return -1; + } + if (pthread_sigmask(SIG_BLOCK, &sigpipe_set, &old_set)) { + return -1; + } + } + + /* Send and save errno. */ + sent = bt_socket_send(fd, buffer, size, 0); + saved_err = errno; + + if (sent == -1 && errno == EPIPE && !sigpipe_was_pending) { + struct timespec timeout = {0, 0}; + int ret; + + do { + ret = sigtimedwait(&sigpipe_set, NULL, &timeout); + } while (ret == -1 && errno == EINTR); + } + if (!sigpipe_was_pending) { + if (pthread_sigmask(SIG_SETMASK, &old_set, NULL)) { + return -1; + } + } + /* Restore send() errno */ + errno = saved_err; + + return sent; +} +#endif + +#endif /* BABELTRACE_COMPAT_SOCKET_HPP */ diff --git a/src/plugins/ctf/lttng-live/viewer-connection.hpp b/src/plugins/ctf/lttng-live/viewer-connection.hpp index 4e17d506..9770092f 100644 --- a/src/plugins/ctf/lttng-live/viewer-connection.hpp +++ b/src/plugins/ctf/lttng-live/viewer-connection.hpp @@ -12,7 +12,7 @@ #include -#include "compat/socket.h" +#include "compat/socket.hpp" #define LTTNG_DEFAULT_NETWORK_VIEWER_PORT 5344 -- 2.34.1