Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | /*
* Copyright (c) 2018 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_SYS_FDTABLE_H_
#define ZEPHYR_INCLUDE_SYS_FDTABLE_H_
#include <stdarg.h>
#include <sys/types.h>
/* FIXME: For native_posix ssize_t, off_t. */
#include <fs/fs.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* File descriptor virtual method table.
* Currently all operations beyond read/write/close go thru ioctl method.
*/
struct fd_op_vtable {
ssize_t (*read)(void *obj, void *buf, size_t sz);
ssize_t (*write)(void *obj, const void *buf, size_t sz);
int (*close)(void *obj);
int (*ioctl)(void *obj, unsigned int request, va_list args);
};
/**
* @brief Reserve file descriptor.
*
* This function allows to reserve a space for file descriptor entry in
* the underlying table, and thus allows caller to fail fast if no free
* descriptor is available. If this function succeeds, z_finalize_fd()
* or z_free_fd() must be called mandatorily.
*
* @return Allocated file descriptor, or -1 in case of error (errno is set)
*/
int z_reserve_fd(void);
/**
* @brief Finalize creation of file descriptor.
*
* This function should be called exactly once after z_reserve_fd(), and
* should not be called in any other case.
*
* @param fd File descriptor previously returned by z_reserve_fd()
* @param obj pointer to I/O object structure
* @param vtable pointer to I/O operation implementations for the object
*/
void z_finalize_fd(int fd, void *obj, const struct fd_op_vtable *vtable);
/**
* @brief Allocate file descriptor for underlying I/O object.
*
* This function combines operations of z_reserve_fd() and z_finalize_fd()
* in one step, and provided for convenience.
*
* @param obj pointer to I/O object structure
* @param vtable pointer to I/O operation implementations for the object
*
* @return Allocated file descriptor, or -1 in case of error (errno is set)
*/
int z_alloc_fd(void *obj, const struct fd_op_vtable *vtable);
/**
* @brief Release reserved file descriptor.
*
* This function may be called once after z_reserve_fd(), and should
* not be called in any other case.
*
* @param fd File descriptor previously returned by z_reserve_fd()
*/
void z_free_fd(int fd);
/**
* @brief Get underlying object pointer from file descriptor.
*
* This function is useful for functions other than read/write/ioctl
* to look up underlying I/O object by fd, optionally checking its
* type (using vtable reference). If fd refers to invalid entry,
* NULL will be returned with errno set to EBADF. If fd is valid,
* but vtable param is not NULL and doesn't match object's vtable,
* NULL is returned and errno set to err param.
*
* @param fd File descriptor previously returned by z_reserve_fd()
* @param vtable Expected object vtable or NULL
* @param err errno value to set if object vtable doesn't match
*
* @return Object pointer or NULL, with errno set
*/
void *z_get_fd_obj(int fd, const struct fd_op_vtable *vtable, int err);
/**
* @brief Get underlying object pointer and vtable pointer from file descriptor.
*
* @param fd File descriptor previously returned by z_reserve_fd()
* @param vtable A pointer to a pointer variable to store the vtable
*
* @return Object pointer or NULL, with errno set
*/
void *z_get_fd_obj_and_vtable(int fd, const struct fd_op_vtable **vtable);
/**
* @brief Call ioctl vmethod on an object using varargs.
*
* We need this helper function because ioctl vmethod is declared to
* take va_list and the only portable way to construct va_list is from
* function's ... parameters.
*
* @param vtable vtable containing ioctl function pointer
* @param obj Object to call ioctl on
* @param request ioctl request number
* @param ... Variadic arguments to ioctl
*/
static inline int z_fdtable_call_ioctl(const struct fd_op_vtable *vtable, void *obj,
unsigned long request, ...)
{
va_list args;
int res;
va_start(args, request);
res = vtable->ioctl(obj, request, args);
va_end(args);
return res;
}
/**
* Request codes for fd_op_vtable.ioctl().
*
* Note that these codes are internal Zephyr numbers, for internal
* Zephyr operations (and subject to change without notice, not part
* of "stable ABI"). These are however expected to co-exist with
* "well-known" POSIX/Linux ioctl numbers, and not clash with them.
*/
enum {
/* Codes below 0x100 are reserved for fcntl() codes. */
ZFD_IOCTL_FSYNC = 0x100,
ZFD_IOCTL_LSEEK,
ZFD_IOCTL_POLL_PREPARE,
ZFD_IOCTL_POLL_UPDATE,
ZFD_IOCTL_POLL_OFFLOAD,
};
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_SYS_FDTABLE_H_ */
|