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