174 lines
5.5 KiB
C
174 lines
5.5 KiB
C
/*
|
|
* Copyright (C) 2019 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup posix_select POSIX select
|
|
* @ingroup posix
|
|
* @brief Select implementation for RIOT
|
|
* @see [The Open Group Base Specification Issue 7]
|
|
* (https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/)
|
|
* @todo Omitted from original specification for now:
|
|
* - Inclusion of `<signal.h>`; no POSIX signal handling implemented
|
|
* in RIOT yet
|
|
* - `pselect()` as it uses `sigset_t` from `<signal.h>`
|
|
* - handling of the `writefds` and `errorfds` parameters of `select()`
|
|
* @todo Currently, only [sockets](@ref posix_sockets) are supported
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Select types
|
|
* @see [The Open Group Base Specification Issue 7, 2018 edition,
|
|
* <sys/select.h>](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/sys_select.h)
|
|
*/
|
|
|
|
#ifndef SYS_SELECT_H
|
|
#define SYS_SELECT_H
|
|
|
|
#include <string.h>
|
|
/* prevent cyclic dependency with newlib/picolibc's `sys/types.h` */
|
|
#if (defined(MODULE_NEWLIB) || defined(MODULE_PICOLIBC)) && \
|
|
!defined(CPU_ESP32) && !defined(CPU_ESP8266)
|
|
#include <sys/_timeval.h>
|
|
#else
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#include "bitfield.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @addtogroup config_posix
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Maximum number of file descriptors in an `fd_set` structure.
|
|
*
|
|
* @note Should have at least the same value as VFS_MAX_OPEN_FILES.
|
|
*
|
|
* Config-exposed version
|
|
*/
|
|
#ifndef CONFIG_POSIX_FD_SET_SIZE
|
|
#define CONFIG_POSIX_FD_SET_SIZE (16)
|
|
#endif
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief @ref core_thread_flags for POSIX select
|
|
*/
|
|
#define POSIX_SELECT_THREAD_FLAG (1U << 3)
|
|
|
|
/* ESP's newlib has this already defined in `sys/types.h` */
|
|
#if !defined(CPU_ESP32) && !defined(CPU_ESP8266)
|
|
/**
|
|
* @brief Maximum number of file descriptors in an `fd_set` structure.
|
|
*
|
|
* POSIX-compliant version.
|
|
*/
|
|
#define FD_SETSIZE (CONFIG_POSIX_FD_SET_SIZE)
|
|
|
|
/**
|
|
* @brief The `fd_set` structure
|
|
*/
|
|
typedef struct {
|
|
BITFIELD(fds, FD_SETSIZE); /**< Bit-field to represent the set of file
|
|
* descriptors */
|
|
} fd_set;
|
|
|
|
/**
|
|
* @brief Removes a file descriptor from an `fd_set` if it is a member
|
|
*
|
|
* @param[in] fd A file descriptor
|
|
* @param[in] fdsetp An `fd_set`
|
|
*/
|
|
static inline void FD_CLR(int fd, fd_set *fdsetp)
|
|
{
|
|
bf_unset(fdsetp->fds, fd);
|
|
}
|
|
|
|
/**
|
|
* @brief Checks if a file descriptor is a member of an `fd_set`
|
|
*
|
|
* @param[in] fd A file descriptor
|
|
* @param[in] fdsetp An `fd_set`
|
|
*
|
|
* @return non-zero value, if @p fd is a member of @p fdsetp
|
|
* @return 0, if @p fd is not a member of @p fdsetp
|
|
*/
|
|
static inline int FD_ISSET(int fd, fd_set *fdsetp)
|
|
{
|
|
return (int)bf_isset(fdsetp->fds, fd);
|
|
}
|
|
|
|
/**
|
|
* @brief Adds a file descriptor from an `fd_set` if it is not already a
|
|
* member
|
|
*
|
|
* @param[in] fd A file descriptor
|
|
* @param[in] fdsetp An `fd_set`
|
|
*/
|
|
static inline void FD_SET(int fd, fd_set *fdsetp)
|
|
{
|
|
bf_set(fdsetp->fds, fd);
|
|
}
|
|
|
|
/**
|
|
* @brief Initializes the descriptor set as an empty set
|
|
*
|
|
* @param[in] fdsetp An `fd_set`
|
|
*/
|
|
static inline void FD_ZERO(fd_set *fdsetp)
|
|
{
|
|
memset(fdsetp->fds, 0, sizeof(fdsetp->fds));
|
|
}
|
|
#endif /* !defined(CPU_ESP32) && !defined(CPU_ESP8266) */
|
|
|
|
/**
|
|
* @brief Examines the given file descriptor sets if they are ready for their
|
|
* respective operation.
|
|
*
|
|
* @param[in] nfds The range of descriptors tested. The first @p nfds
|
|
* descriptors shall be checked in each set; that is,
|
|
* the descriptors from zero through @p nfds - 1 in the
|
|
* descriptor sets shall be examined.
|
|
* @param[in,out] readfds The set of file descriptors to be checked for being
|
|
* ready to read. Indicates on output which file
|
|
* descriptors are ready to read. May be NULL to check
|
|
* no file descriptors.
|
|
* @param[in,out] writefds The set of file descriptors to be checked for being
|
|
* ready to write. Indicates on output which file
|
|
* descriptors are ready to write. May be NULL to check
|
|
* no file descriptors.
|
|
* **As only sockets are supported for now, these will
|
|
* be ignored**
|
|
* @param[in,out] errorfds The set of file descriptors to be checked for being
|
|
* error conditions pending. Indicates on output which
|
|
* file descriptors have error conditions pending. May
|
|
* be NULL to check no file descriptors.
|
|
* **As only sockets are supported for now, these will
|
|
* be ignored**
|
|
* @param[in] timeout Timeout for select to block until one or more of the
|
|
* checked file descriptors is ready. Set timeout
|
|
* to all-zero to return immediately without blocking.
|
|
* May be NULL to block indefinitely.
|
|
*
|
|
* @return number of members added to the file descriptor sets on success.
|
|
* @return -1 on error, `errno` is set to indicate the error.
|
|
*/
|
|
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
|
|
struct timeval *timeout);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* SYS_SELECT_H */
|
|
/** @} */
|