Line data Source code
1 0 : /*
2 : * Copyright (c) 2018 Linaro Limited
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 : #ifndef ZEPHYR_INCLUDE_SYS_FDTABLE_H_
7 : #define ZEPHYR_INCLUDE_SYS_FDTABLE_H_
8 :
9 : #include <stdarg.h>
10 : #include <time.h>
11 :
12 : /* FIXME: For native_posix ssize_t, off_t. */
13 : #include <sys/types.h>
14 : #include <zephyr/kernel.h>
15 : #include <zephyr/sys/util.h>
16 :
17 : #ifdef CONFIG_PICOLIBC
18 : #define ZVFS_O_APPEND 0x0400
19 : #define ZVFS_O_CREAT 0x0040
20 : #define ZVFS_O_TRUNC 0x0200
21 : #else
22 0 : #define ZVFS_O_APPEND 0x0008
23 0 : #define ZVFS_O_CREAT 0x0200
24 0 : #define ZVFS_O_TRUNC 0x0400
25 : #endif
26 :
27 0 : #define ZVFS_O_RDONLY 00
28 0 : #define ZVFS_O_WRONLY 01
29 0 : #define ZVFS_O_RDWR 02
30 :
31 0 : #define ZVFS_O_EXCL 0x0800
32 0 : #define ZVFS_O_NONBLOCK 0x4000
33 :
34 0 : #define ZVFS_F_DUPFD 0
35 0 : #define ZVFS_F_GETFL 3
36 0 : #define ZVFS_F_SETFL 4
37 :
38 : /* File mode bits */
39 0 : #define ZVFS_MODE_IFMT 0170000
40 0 : #define ZVFS_MODE_UNSPEC 0000000
41 0 : #define ZVFS_MODE_IFIFO 0010000
42 0 : #define ZVFS_MODE_IFCHR 0020000
43 0 : #define ZVFS_MODE_IMSGQ 0030000
44 0 : #define ZVFS_MODE_IFDIR 0040000
45 0 : #define ZVFS_MODE_IFSEM 0050000
46 0 : #define ZVFS_MODE_IFBLK 0060000
47 0 : #define ZVFS_MODE_IFSHM 0070000
48 0 : #define ZVFS_MODE_IFREG 0100000
49 0 : #define ZVFS_MODE_IFLNK 0120000
50 0 : #define ZVFS_MODE_IFSOCK 0140000
51 :
52 0 : #define ZVFS_POLLIN BIT(0)
53 0 : #define ZVFS_POLLPRI BIT(1)
54 0 : #define ZVFS_POLLOUT BIT(2)
55 0 : #define ZVFS_POLLERR BIT(3)
56 0 : #define ZVFS_POLLHUP BIT(4)
57 0 : #define ZVFS_POLLNVAL BIT(5)
58 :
59 : #ifdef __cplusplus
60 : extern "C" {
61 : #endif
62 :
63 : /* FIXME: use k_off_t and k_ssize_t to avoid the POSIX->Zephyr->POSIX dependency cycle */
64 : #ifdef CONFIG_NEWLIB_LIBC
65 : #ifndef _OFF_T_DECLARED
66 : typedef __off_t off_t;
67 : #define _OFF_T_DECLARED
68 : #endif
69 : #ifndef _SSIZE_T_DECLARED
70 : typedef _ssize_t ssize_t;
71 : #define _SSIZE_T_DECLARED
72 : #endif
73 : #endif
74 :
75 : /**
76 : * File descriptor virtual method table.
77 : * Currently all operations beyond read/write/close go thru ioctl method.
78 : */
79 1 : struct fd_op_vtable {
80 : union {
81 0 : ssize_t (*read)(void *obj, void *buf, size_t sz);
82 0 : ssize_t (*read_offs)(void *obj, void *buf, size_t sz, size_t offset);
83 0 : };
84 : union {
85 0 : ssize_t (*write)(void *obj, const void *buf, size_t sz);
86 0 : ssize_t (*write_offs)(void *obj, const void *buf, size_t sz, size_t offset);
87 0 : };
88 : union {
89 0 : int (*close)(void *obj);
90 0 : int (*close2)(void *obj, int fd);
91 0 : };
92 0 : int (*ioctl)(void *obj, unsigned int request, va_list args);
93 : };
94 :
95 : /**
96 : * @brief Reserve file descriptor.
97 : *
98 : * This function allows to reserve a space for file descriptor entry in
99 : * the underlying table, and thus allows caller to fail fast if no free
100 : * descriptor is available. If this function succeeds, zvfs_finalize_fd()
101 : * or zvfs_free_fd() must be called mandatorily.
102 : *
103 : * @return Allocated file descriptor, or -1 in case of error (errno is set)
104 : */
105 1 : int zvfs_reserve_fd(void);
106 :
107 : /**
108 : * @brief Finalize creation of file descriptor, with type.
109 : *
110 : * This function should be called exactly once after zvfs_reserve_fd(), and
111 : * should not be called in any other case.
112 : *
113 : * The difference between this function and @ref zvfs_finalize_fd is that the
114 : * latter does not relay type information of the created file descriptor.
115 : *
116 : * Values permitted for @a mode are one of `ZVFS_MODE_..`.
117 : *
118 : * @param fd File descriptor previously returned by zvfs_reserve_fd()
119 : * @param obj pointer to I/O object structure
120 : * @param vtable pointer to I/O operation implementations for the object
121 : * @param mode File type as specified above.
122 : */
123 1 : void zvfs_finalize_typed_fd(int fd, void *obj, const struct fd_op_vtable *vtable, uint32_t mode);
124 :
125 : /**
126 : * @brief Finalize creation of file descriptor.
127 : *
128 : * This function should be called exactly once after zvfs_reserve_fd(), and
129 : * should not be called in any other case.
130 : *
131 : * @param fd File descriptor previously returned by zvfs_reserve_fd()
132 : * @param obj pointer to I/O object structure
133 : * @param vtable pointer to I/O operation implementations for the object
134 : */
135 1 : static inline void zvfs_finalize_fd(int fd, void *obj, const struct fd_op_vtable *vtable)
136 : {
137 : zvfs_finalize_typed_fd(fd, obj, vtable, ZVFS_MODE_UNSPEC);
138 : }
139 :
140 : /**
141 : * @brief Allocate file descriptor for underlying I/O object.
142 : *
143 : * This function combines operations of zvfs_reserve_fd() and zvfs_finalize_fd()
144 : * in one step, and provided for convenience.
145 : *
146 : * @param obj pointer to I/O object structure
147 : * @param vtable pointer to I/O operation implementations for the object
148 : *
149 : * @return Allocated file descriptor, or -1 in case of error (errno is set)
150 : */
151 1 : int zvfs_alloc_fd(void *obj, const struct fd_op_vtable *vtable);
152 :
153 : /**
154 : * @brief Release reserved file descriptor.
155 : *
156 : * This function may be called once after zvfs_reserve_fd(), and should
157 : * not be called in any other case.
158 : *
159 : * @param fd File descriptor previously returned by zvfs_reserve_fd()
160 : */
161 1 : void zvfs_free_fd(int fd);
162 :
163 : /**
164 : * @brief Get underlying object pointer from file descriptor.
165 : *
166 : * This function is useful for functions other than read/write/ioctl
167 : * to look up underlying I/O object by fd, optionally checking its
168 : * type (using vtable reference). If fd refers to invalid entry,
169 : * NULL will be returned with errno set to EBADF. If fd is valid,
170 : * but vtable param is not NULL and doesn't match object's vtable,
171 : * NULL is returned and errno set to err param.
172 : *
173 : * @param fd File descriptor previously returned by zvfs_reserve_fd()
174 : * @param vtable Expected object vtable or NULL
175 : * @param err errno value to set if object vtable doesn't match
176 : *
177 : * @return Object pointer or NULL, with errno set
178 : */
179 1 : void *zvfs_get_fd_obj(int fd, const struct fd_op_vtable *vtable, int err);
180 :
181 : /**
182 : * @brief Get underlying object pointer and vtable pointer from file descriptor.
183 : *
184 : * @param fd File descriptor previously returned by zvfs_reserve_fd()
185 : * @param vtable A pointer to a pointer variable to store the vtable
186 : * @param lock An optional pointer to a pointer variable to store the mutex
187 : * preventing concurrent descriptor access. The lock is not taken,
188 : * it is just returned for the caller to use if necessary. Pass NULL
189 : * if the lock is not needed by the caller.
190 : *
191 : * @return Object pointer or NULL, with errno set
192 : */
193 1 : void *zvfs_get_fd_obj_and_vtable(int fd, const struct fd_op_vtable **vtable,
194 : struct k_mutex **lock);
195 :
196 : /**
197 : * @brief Get the mutex and condition variable associated with the given object and vtable.
198 : *
199 : * @param obj Object previously returned by a call to e.g. @ref zvfs_get_fd_obj.
200 : * @param vtable A pointer the vtable associated with @p obj.
201 : * @param lock An optional pointer to a pointer variable to store the mutex
202 : * preventing concurrent descriptor access. The lock is not taken,
203 : * it is just returned for the caller to use if necessary. Pass NULL
204 : * if the lock is not needed by the caller.
205 : * @param cond An optional pointer to a pointer variable to store the condition variable
206 : * to notify waiting threads in the case of concurrent descriptor access. Pass NULL
207 : * if the condition variable is not needed by the caller.
208 : *
209 : * @return `true` on success, `false` otherwise.
210 : */
211 1 : bool zvfs_get_obj_lock_and_cond(void *obj, const struct fd_op_vtable *vtable, struct k_mutex **lock,
212 : struct k_condvar **cond);
213 :
214 : /**
215 : * @brief Call ioctl vmethod on an object using varargs.
216 : *
217 : * We need this helper function because ioctl vmethod is declared to
218 : * take va_list and the only portable way to construct va_list is from
219 : * function's ... parameters.
220 : *
221 : * @param vtable vtable containing ioctl function pointer
222 : * @param obj Object to call ioctl on
223 : * @param request ioctl request number
224 : * @param ... Variadic arguments to ioctl
225 : */
226 1 : static inline int zvfs_fdtable_call_ioctl(const struct fd_op_vtable *vtable, void *obj,
227 : unsigned long request, ...)
228 : {
229 : va_list args;
230 : int res;
231 :
232 : va_start(args, request);
233 : res = vtable->ioctl(obj, request, args);
234 : va_end(args);
235 :
236 : return res;
237 : }
238 :
239 0 : struct zvfs_pollfd {
240 0 : int fd;
241 0 : short events;
242 0 : short revents;
243 : };
244 :
245 0 : __syscall int zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout);
246 :
247 0 : struct zvfs_fd_set {
248 0 : uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32];
249 : };
250 :
251 : /** @brief Number of file descriptors which can be added @ref zvfs_fd_set */
252 1 : #define ZVFS_FD_SETSIZE (sizeof(((struct zvfs_fd_set *)0)->bitset) * 8)
253 :
254 0 : void ZVFS_FD_CLR(int fd, struct zvfs_fd_set *fdset);
255 0 : int ZVFS_FD_ISSET(int fd, struct zvfs_fd_set *fdset);
256 0 : void ZVFS_FD_SET(int fd, struct zvfs_fd_set *fdset);
257 0 : void ZVFS_FD_ZERO(struct zvfs_fd_set *fdset);
258 :
259 0 : __syscall int zvfs_select(int nfds, struct zvfs_fd_set *ZRESTRICT readfds,
260 : struct zvfs_fd_set *ZRESTRICT writefds,
261 : struct zvfs_fd_set *ZRESTRICT errorfds,
262 : const struct timespec *ZRESTRICT timeout, const void *ZRESTRICT sigmask);
263 :
264 : /**
265 : * Request codes for fd_op_vtable.ioctl().
266 : *
267 : * Note that these codes are internal Zephyr numbers, for internal
268 : * Zephyr operations (and subject to change without notice, not part
269 : * of "stable ABI"). These are however expected to co-exist with
270 : * "well-known" POSIX/Linux ioctl numbers, and not clash with them.
271 : */
272 0 : enum {
273 : /* Codes below 0x100 are reserved for fcntl() codes. */
274 : ZFD_IOCTL_FSYNC = 0x100,
275 : ZFD_IOCTL_LSEEK,
276 : ZFD_IOCTL_POLL_PREPARE,
277 : ZFD_IOCTL_POLL_UPDATE,
278 : ZFD_IOCTL_POLL_OFFLOAD,
279 : ZFD_IOCTL_SET_LOCK,
280 : ZFD_IOCTL_STAT,
281 : ZFD_IOCTL_TRUNCATE,
282 : ZFD_IOCTL_MMAP,
283 :
284 : /* Codes above 0x5400 and below 0x5500 are reserved for termios, FIO, etc */
285 : ZFD_IOCTL_FIONREAD = 0x541B,
286 : ZFD_IOCTL_FIONBIO = 0x5421,
287 : };
288 :
289 : #ifdef __cplusplus
290 : }
291 : #endif
292 :
293 : #include <zephyr/syscalls/fdtable.h>
294 :
295 : #endif /* ZEPHYR_INCLUDE_SYS_FDTABLE_H_ */
|