1 /*
2  * Copyright (c) 2019 Linaro Limited
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /** @file socket_select.h
8  *
9  * @brief BSD select support functions.
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_NET_SOCKET_SELECT_H_
13 #define ZEPHYR_INCLUDE_NET_SOCKET_SELECT_H_
14 
15 /**
16  * @brief BSD Sockets compatible API
17  * @defgroup bsd_sockets BSD Sockets compatible API
18  * @ingroup networking
19  * @{
20  */
21 
22 #include <time.h>
23 
24 #include <zephyr/toolchain.h>
25 #include <zephyr/net/socket_types.h>
26 #include <zephyr/sys/fdtable.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /** Socket file descriptor set. */
33 typedef struct zvfs_fd_set zsock_fd_set;
34 
35 /**
36  * @brief Legacy function to poll multiple sockets for events
37  *
38  * @details
39  * See POSIX.1-2017 article
40  * http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html
41  * for normative description. This function is provided to ease porting of
42  * existing code and not recommended for usage due to its inefficiency,
43  * use zsock_poll() instead. In Zephyr this function works only with
44  * sockets, not arbitrary file descriptors.
45  * This function is also exposed as `select()`
46  * if @kconfig{CONFIG_POSIX_API} is defined (in which case
47  * it may conflict with generic POSIX `select()` function).
48  */
zsock_select(int nfds,zsock_fd_set * readfds,zsock_fd_set * writefds,zsock_fd_set * exceptfds,struct zsock_timeval * timeout)49 static inline int zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds,
50 			       zsock_fd_set *exceptfds, struct zsock_timeval *timeout)
51 {
52 	struct timespec to = {
53 		.tv_sec = (timeout == NULL) ? 0 : timeout->tv_sec,
54 		.tv_nsec = (long)((timeout == NULL) ? 0 : timeout->tv_usec * NSEC_PER_USEC)};
55 
56 	return zvfs_select(nfds, readfds, writefds, exceptfds, (timeout == NULL) ? NULL : &to,
57 			   NULL);
58 }
59 
60 /** Number of file descriptors which can be added to zsock_fd_set */
61 #define ZSOCK_FD_SETSIZE ZVFS_FD_SETSIZE
62 
63 /**
64  * @brief Initialize (clear) fd_set
65  *
66  * @details
67  * See POSIX.1-2017 article
68  * http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html
69  * for normative description.
70  * This function is also exposed as `FD_ZERO()`
71  * if @kconfig{CONFIG_POSIX_API} is defined.
72  */
ZSOCK_FD_ZERO(zsock_fd_set * set)73 static inline void ZSOCK_FD_ZERO(zsock_fd_set *set)
74 {
75 	ZVFS_FD_ZERO(set);
76 }
77 
78 /**
79  * @brief Check whether socket is a member of fd_set
80  *
81  * @details
82  * See POSIX.1-2017 article
83  * http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html
84  * for normative description.
85  * This function is also exposed as `FD_ISSET()`
86  * if @kconfig{CONFIG_POSIX_API} is defined.
87  */
ZSOCK_FD_ISSET(int fd,zsock_fd_set * set)88 static inline int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set)
89 {
90 	return ZVFS_FD_ISSET(fd, set);
91 }
92 
93 /**
94  * @brief Remove socket from fd_set
95  *
96  * @details
97  * See POSIX.1-2017 article
98  * http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html
99  * for normative description.
100  * This function is also exposed as `FD_CLR()`
101  * if @kconfig{CONFIG_POSIX_API} is defined.
102  */
ZSOCK_FD_CLR(int fd,zsock_fd_set * set)103 static inline void ZSOCK_FD_CLR(int fd, zsock_fd_set *set)
104 {
105 	ZVFS_FD_CLR(fd, set);
106 }
107 
108 /**
109  * @brief Add socket to fd_set
110  *
111  * @details
112  * See POSIX.1-2017 article
113  * http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html
114  * for normative description.
115  * This function is also exposed as `FD_SET()`
116  * if @kconfig{CONFIG_POSIX_API} is defined.
117  */
ZSOCK_FD_SET(int fd,zsock_fd_set * set)118 static inline void ZSOCK_FD_SET(int fd, zsock_fd_set *set)
119 {
120 	ZVFS_FD_SET(fd, set);
121 }
122 
123 #ifdef __cplusplus
124 }
125 #endif
126 
127 /**
128  * @}
129  */
130 
131 #endif /* ZEPHYR_INCLUDE_NET_SOCKET_SELECT_H_ */
132