mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-14 08:55:22 +00:00
Currently zsock_timeval implementation uses long type for both tv_sec and tv_usec fields. In the select method timeval type is directly casted on zsock_timeval, but in some cases (e.g. when using CONFIG_POSIX_API and some specific libc version) both types have fields of different sizes, what may lead to assigning them incorrect values. Using types declared by the used libc in the CONFIG_POSIX_API=y case will let to keep timeval and zsock_timeval types compatible. Signed-off-by: Kamil Kasperczyk <kamil.kasperczyk@nordicsemi.no>
177 lines
4.2 KiB
C
177 lines
4.2 KiB
C
/*
|
|
* Copyright (c) 2019 Linaro Limited
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_INCLUDE_NET_SOCKET_SELECT_H_
|
|
#define ZEPHYR_INCLUDE_NET_SOCKET_SELECT_H_
|
|
|
|
/**
|
|
* @brief BSD Sockets compatible API
|
|
* @defgroup bsd_sockets BSD Sockets compatible API
|
|
* @ingroup networking
|
|
* @{
|
|
*/
|
|
|
|
#include <zephyr/types.h>
|
|
|
|
#ifdef CONFIG_POSIX_API
|
|
#ifdef __NEWLIB__
|
|
#include <sys/_timeval.h>
|
|
#else
|
|
#include <sys/types.h>
|
|
#endif /* __NEWLIB__ */
|
|
#endif /* CONFIG_POSIX_API */
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifdef CONFIG_POSIX_API
|
|
/* Rely on the underlying libc definition */
|
|
#ifdef __NEWLIB__
|
|
#define zsock_timeval timeval
|
|
#else
|
|
/* workaround for older Newlib 2.x, as it lacks sys/_timeval.h */
|
|
struct zsock_timeval {
|
|
time_t tv_sec;
|
|
suseconds_t tv_usec;
|
|
};
|
|
#endif /* __NEWLIB__ */
|
|
#else
|
|
struct zsock_timeval {
|
|
/* Using longs, as many (?) implementations seem to use it. */
|
|
long tv_sec;
|
|
long tv_usec;
|
|
};
|
|
#endif /* CONFIG_POSIX_API */
|
|
|
|
typedef struct zsock_fd_set {
|
|
uint32_t bitset[(CONFIG_POSIX_MAX_FDS + 31) / 32];
|
|
} zsock_fd_set;
|
|
|
|
|
|
/**
|
|
* @brief Legacy function to poll multiple sockets for events
|
|
*
|
|
* @details
|
|
* @rst
|
|
* See `POSIX.1-2017 article
|
|
* <http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html>`__
|
|
* for normative description. This function is provided to ease porting of
|
|
* existing code and not recommended for usage due to its inefficiency,
|
|
* use :c:func:`zsock_poll()` instead. In Zephyr this function works only with
|
|
* sockets, not arbitrary file descriptors.
|
|
* This function is also exposed as ``select()``
|
|
* if :option:`CONFIG_NET_SOCKETS_POSIX_NAMES` is defined (in which case
|
|
* it may conflict with generic POSIX ``select()`` function).
|
|
* @endrst
|
|
*/
|
|
int zsock_select(int nfds, zsock_fd_set *readfds, zsock_fd_set *writefds,
|
|
zsock_fd_set *exceptfds, struct zsock_timeval *timeout);
|
|
|
|
/** Number of file descriptors which can be added to zsock_fd_set */
|
|
#define ZSOCK_FD_SETSIZE (sizeof(((zsock_fd_set *)0)->bitset) * 8)
|
|
|
|
/**
|
|
* @brief Initialize (clear) fd_set
|
|
*
|
|
* @details
|
|
* @rst
|
|
* See `POSIX.1-2017 article
|
|
* <http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html>`__
|
|
* for normative description.
|
|
* This function is also exposed as ``FD_ZERO()``
|
|
* if :option:`CONFIG_NET_SOCKETS_POSIX_NAMES` is defined.
|
|
* @endrst
|
|
*/
|
|
void ZSOCK_FD_ZERO(zsock_fd_set *set);
|
|
|
|
/**
|
|
* @brief Check whether socket is a member of fd_set
|
|
*
|
|
* @details
|
|
* @rst
|
|
* See `POSIX.1-2017 article
|
|
* <http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html>`__
|
|
* for normative description.
|
|
* This function is also exposed as ``FD_ISSET()``
|
|
* if :option:`CONFIG_NET_SOCKETS_POSIX_NAMES` is defined.
|
|
* @endrst
|
|
*/
|
|
int ZSOCK_FD_ISSET(int fd, zsock_fd_set *set);
|
|
|
|
/**
|
|
* @brief Remove socket from fd_set
|
|
*
|
|
* @details
|
|
* @rst
|
|
* See `POSIX.1-2017 article
|
|
* <http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html>`__
|
|
* for normative description.
|
|
* This function is also exposed as ``FD_CLR()``
|
|
* if :option:`CONFIG_NET_SOCKETS_POSIX_NAMES` is defined.
|
|
* @endrst
|
|
*/
|
|
void ZSOCK_FD_CLR(int fd, zsock_fd_set *set);
|
|
|
|
/**
|
|
* @brief Add socket to fd_set
|
|
*
|
|
* @details
|
|
* @rst
|
|
* See `POSIX.1-2017 article
|
|
* <http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html>`__
|
|
* for normative description.
|
|
* This function is also exposed as ``FD_SET()``
|
|
* if :option:`CONFIG_NET_SOCKETS_POSIX_NAMES` is defined.
|
|
* @endrst
|
|
*/
|
|
void ZSOCK_FD_SET(int fd, zsock_fd_set *set);
|
|
|
|
#ifdef CONFIG_NET_SOCKETS_POSIX_NAMES
|
|
|
|
#define fd_set zsock_fd_set
|
|
#define timeval zsock_timeval
|
|
#define FD_SETSIZE ZSOCK_FD_SETSIZE
|
|
|
|
static inline int select(int nfds, zsock_fd_set *readfds,
|
|
zsock_fd_set *writefds, zsock_fd_set *exceptfds,
|
|
struct timeval *timeout)
|
|
{
|
|
return zsock_select(nfds, readfds, writefds, exceptfds, timeout);
|
|
}
|
|
|
|
static inline void FD_ZERO(zsock_fd_set *set)
|
|
{
|
|
ZSOCK_FD_ZERO(set);
|
|
}
|
|
|
|
static inline int FD_ISSET(int fd, zsock_fd_set *set)
|
|
{
|
|
return ZSOCK_FD_ISSET(fd, set);
|
|
}
|
|
|
|
static inline void FD_CLR(int fd, zsock_fd_set *set)
|
|
{
|
|
ZSOCK_FD_CLR(fd, set);
|
|
}
|
|
|
|
static inline void FD_SET(int fd, zsock_fd_set *set)
|
|
{
|
|
ZSOCK_FD_SET(fd, set);
|
|
}
|
|
|
|
#endif /* CONFIG_NET_SOCKETS_POSIX_NAMES */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* ZEPHYR_INCLUDE_NET_SOCKET_SELECT_H_ */
|