RIOT/sys/posix/include/sys/select.h

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 */
/** @} */