|
| 1 | +/* HASH CRC-32:0xecf5b441 */ |
| 2 | +/* Copyright (c) 2019-2025 Griefer@Work * |
| 3 | + * * |
| 4 | + * This software is provided 'as-is', without any express or implied * |
| 5 | + * warranty. In no event will the authors be held liable for any damages * |
| 6 | + * arising from the use of this software. * |
| 7 | + * * |
| 8 | + * Permission is granted to anyone to use this software for any purpose, * |
| 9 | + * including commercial applications, and to alter it and redistribute it * |
| 10 | + * freely, subject to the following restrictions: * |
| 11 | + * * |
| 12 | + * 1. The origin of this software must not be misrepresented; you must not * |
| 13 | + * claim that you wrote the original software. If you use this software * |
| 14 | + * in a product, an acknowledgement (see the following) in the product * |
| 15 | + * documentation is required: * |
| 16 | + * Portions Copyright (c) 2019-2025 Griefer@Work * |
| 17 | + * 2. Altered source versions must be plainly marked as such, and must not be * |
| 18 | + * misrepresented as being the original software. * |
| 19 | + * 3. This notice may not be removed or altered from any source distribution. * |
| 20 | + */ |
| 21 | +#ifndef _KOS_FD_H |
| 22 | +#define _KOS_FD_H 1 |
| 23 | + |
| 24 | +#include <__stdinc.h> |
| 25 | +#include <__crt.h> |
| 26 | + |
| 27 | +#ifdef __COMPILER_HAVE_PRAGMA_GCC_SYSTEM_HEADER |
| 28 | +#pragma GCC system_header |
| 29 | +#endif /* __COMPILER_HAVE_PRAGMA_GCC_SYSTEM_HEADER */ |
| 30 | + |
| 31 | + |
| 32 | +#include <kos/io.h> |
| 33 | +#include <kos/ioctl/file.h> |
| 34 | +#include <kos/types.h> |
| 35 | + |
| 36 | +#ifdef __CC__ |
| 37 | +__SYSDECL_BEGIN |
| 38 | + |
| 39 | +/* >> fd_polltest(3) |
| 40 | + * Convenience wrapper around `FD_IOC_POLLTEST', used to test which (if |
| 41 | + * any) operations applicable may be performed without blocking right now. |
| 42 | + * Poll testing is primarily used internally by the kernel for `ppoll(2)', |
| 43 | + * `pselect(2)', `select(2)', etc., but you can also check what can be done |
| 44 | + * right now using this function. Note however that the info returned here |
| 45 | + * may already be out-of-date by the time this function returns. |
| 46 | + * |
| 47 | + * @param: what: What to test for (set of `POLL') |
| 48 | + * @return: * : What can be done without blocking (may not longer be up-to-date) */ |
| 49 | +__CDECLARE_OPT(__ATTR_WUNUSED __ATTR_FDARG(1),poll_mode_t,__NOTHROW_NCX,fd_polltest,(fd_t __fd, poll_mode_t __what),(__fd,__what)) |
| 50 | +/* >> fd_cast(3) |
| 51 | + * Convenience wrapper around `FD_IOC_CAST', used to cast the object behind |
| 52 | + * a given file descriptor `fd' into another, related kernel object, and |
| 53 | + * store the result in a new file descriptor. |
| 54 | + * For example: you can cast a file as returned by `open(2)' into various sub-objects: |
| 55 | + * - HANDLE_TYPE_MFILE: Memory-file / inode descriptor |
| 56 | + * - HANDLE_TYPE_DIRENT: Directory entry name (file-path descriptor w/o leading path) |
| 57 | + * - HANDLE_TYPE_PATH: Filename path (file-path descriptor w/o trailing filename) |
| 58 | + * @param: fd: The file descriptor to cast |
| 59 | + * @param: type: Wanted cast target type (one of `HANDLE_TYPE_*') |
| 60 | + * @param: mode: Set of `IO_CLOEXEC | IO_CLOFORK' |
| 61 | + * @return: * : The new file descriptor |
| 62 | + * @return: -1: [errno=ENOTSOCK] Given `fd' cannot be cast to `type' (which was `HANDLE_TYPE_SOCKET') |
| 63 | + * @return: -1: [errno=EBADFD] Given `fd' cannot be cast to specified `type' */ |
| 64 | +__CDECLARE_OPT(__ATTR_WUNUSED __ATTR_FDARG(1),fd_t,__NOTHROW_NCX,fd_cast,(fd_t __fd, uint32_t __type, __iomode_t __mode),(__fd,__type,__mode)) |
| 65 | +/* >> fd_msalign(3) |
| 66 | + * Convenience wrapper around `FILE_IOC_MSALIGN', used to create a miss-aligned, |
| 67 | + * mmap'able alias of the backing data of `fd'. For this purpose, `*p_offset' |
| 68 | + * is allowed to be any arbitrary value on entry, and the alias returned by this |
| 69 | + * function will contain data offset by `*p_offset & (getpagesize() - 1)'. This |
| 70 | + * offset is then returned from `*p_offset' upon return, meaning that you may re- |
| 71 | + * use `OUT(*p_offset)' as an argument to `mmap(2)' and have the contents of the |
| 72 | + * original file appear shifted to the start of a page. |
| 73 | + * |
| 74 | + * For more information, see the description on `struct file_msalign' |
| 75 | + * |
| 76 | + * @param: mode: Set of `IO_CLOEXEC | IO_CLOFORK' |
| 77 | + * @return: * : A file descriptor for the newly created misaligned wrapper |
| 78 | + * @return: -1: Error (s.a. `errno') */ |
| 79 | +__CDECLARE_OPT(__ATTR_WUNUSED __ATTR_FDARG(1) __ATTR_INOUT(2),fd_t,__NOTHROW_NCX,fd_msalign,(fd_t __fd, uint64_t *__p_offset, __iomode_t __mode),(__fd,__p_offset,__mode)) |
| 80 | +/* >> fd_subregion(3) |
| 81 | + * Convenience wrapper around `FILE_IOC_SUBREGION', used to create a sub-region |
| 82 | + * alias of another file. Said alias can then be shared and used like any other |
| 83 | + * file descriptor (with the primary purpose being that it can be shared between |
| 84 | + * processes), whilst only allowing access to the specific sub-region of the |
| 85 | + * original file. Additionally: |
| 86 | + * - You can also create further sub-regions of other sub-regions |
| 87 | + * - You can (without risking OOM) force-revoke all memory mappings and |
| 88 | + * future accesses to data that used-to-be-described by some sub-region. |
| 89 | + * s.a. `fd_delregion(3)' |
| 90 | + * - The primary intended use of this function and `fd_delregion(3)' is to |
| 91 | + * allow a user-space video driver/compositor to load some small portion |
| 92 | + * of video memory, or the display's LFB, and share direct access to that |
| 93 | + * region of physical memory with less privileged processes, whilst also |
| 94 | + * being able to revoke that access at a moment's notice (such as when a |
| 95 | + * window that used to be unobstructed suddenly has another window in-front, |
| 96 | + * meaning that the compositor has to revoke direct screen access from the |
| 97 | + * window, and any process that might has live memory mappings of it). |
| 98 | + * @param: base: The page-aligned starting address of the sub-region |
| 99 | + * @param: num_bytes: The size of the region (in bytes), starting at `base' |
| 100 | + * @param: mode: Set of `IO_CLOEXEC | IO_CLOFORK' |
| 101 | + * @return: * : A file descriptor for the newly created sub-region |
| 102 | + * @return: -1: [errno=EACCES] Given `fd' was not opened for read+write |
| 103 | + * @return: -1: [errno=EINVAL] Given `base' / `num_bytes' are improperly aligned, or too large |
| 104 | + * @return: -1: [errno=EINVAL] Given `base + num_bytes' is greater than the size of `fd' |
| 105 | + * @return: -1: [errno=EPERM] Given `fd' uses a custom mmap mechanism (doesn't |
| 106 | + * support "raw" I/O), and isn't another sub-region |
| 107 | + * @return: -1: [errno=ENOMEM] Insufficient memory */ |
| 108 | +__CDECLARE_OPT(__ATTR_WUNUSED __ATTR_FDARG(1),fd_t,__NOTHROW_NCX,fd_subregion,(fd_t __fd, uint64_t __base, uint64_t __num_bytes, __iomode_t __mode),(__fd,__base,__num_bytes,__mode)) |
| 109 | +/* >> fd_delregion(3) |
| 110 | + * Convenience wrapper around `FILE_IOC_DELREGION', used to system-wide force-revoke |
| 111 | + * all access to memory described by a sub-region file descriptor, as previously |
| 112 | + * created using `fd_subregion(3)': |
| 113 | + * - Any memory-mappings made using `fd' or other sub-regions derived from `fd' |
| 114 | + * are forcefully replaced with mappings of `/dev/void' (meaning that while they |
| 115 | + * are still mapped into memory and can be read/written, only garbled data will |
| 116 | + * be read, and any writes will be lost) |
| 117 | + * - Any future calls to `pread(2)' or `pwrite(2)' performed on `fd' or some other |
| 118 | + * sub-region derived from `fd' will similarly behave as though `fd' were a file |
| 119 | + * descriptor for `/dev/void' |
| 120 | + * - If `fd' itself was derived from another sub-region, that "parent" sub-region, |
| 121 | + * as well as any "sibling" sub-region will *NOT* be revoked (meaning that this |
| 122 | + * function only ever revokes access from anyone that had been given `fd'). |
| 123 | + * |
| 124 | + * @return: 0 : Success: access to `fd' has been revoked / replaced with `/dev/void' |
| 125 | + * @return: -1: [errno=EPERM] Given `fd' is a sub-region, as returned by `fd_subregion(3)' */ |
| 126 | +__CDECLARE_OPT(__ATTR_FDARG(1),int,__NOTHROW_NCX,fd_delregion,(fd_t __fd),(__fd)) |
| 127 | +/* >> fd_tailread(3) |
| 128 | + * Convenience wrapper around `FILE_IOC_TAILREAD', which can be used to perform a |
| 129 | + * so-called "tail-read" from some given file `fd'. A tail-read essentially does |
| 130 | + * what is done by `tail -f' on the CLI, meaning where `read(2)' / `pread(2)' |
| 131 | + * would return `0' when trying to read past the end of a file, this function |
| 132 | + * will block until at least `1' byte could be read at `offset'. |
| 133 | + * |
| 134 | + * @param: fd: The file to read from. |
| 135 | + * @param: buf: Output buffer for read data. At most `bufsize' bytes will be read |
| 136 | + * @param: bufsize: Max # of bytes to read. |
| 137 | + * @param: offset: Starting offset for where to start reading. |
| 138 | + * @return: > 0: The actual # of bytes that were read (always `<= bufsize') |
| 139 | + * @return: 0 : Nothing was read (only happens when `bufsize == 0') |
| 140 | + * @return: -1: [errno=*] Failed to read data (errors are the same as for `read(2)' and `pread(2)') */ |
| 141 | +__CDECLARE_OPT(__ATTR_WUNUSED __ATTR_FDREAD(1) __ATTR_OUTS(2, 3),ssize_t,__NOTHROW_NCX,fd_tailread,(fd_t __fd, void *__buf, size_t __bufsize, uint64_t __offset),(__fd,__buf,__bufsize,__offset)) |
| 142 | +/* >> fd_trim(3) |
| 143 | + * Convenience wrapper around `FILE_IOC_TRIM', which can be used |
| 144 | + * to trim/unload parts of the filesystem/mmap cache of a file. |
| 145 | + * |
| 146 | + * @param: fd: The file whose caches to trim. |
| 147 | + * @param: base: Starting offset for where to start trimming (will be rounded down) |
| 148 | + * @param: num_bytes: Number of bytes that will be trimmed (will be rounded up) |
| 149 | + * @param: mode: Trim-mode (one of `FILE_TRIM_MODE_*') |
| 150 | + * @return: * : The # of bytes that were trimmed |
| 151 | + * @return: (uint64_t)-1: Error (s.a. `errno') */ |
| 152 | +__CDECLARE_OPT(__ATTR_FDARG(1),uint64_t,__NOTHROW_NCX,fd_trim,(fd_t __fd, uint64_t __base, uint64_t __num_bytes, uint32_t __mode),(__fd,__base,__num_bytes,__mode)) |
| 153 | + |
| 154 | +__SYSDECL_END |
| 155 | +#endif /* __CC__ */ |
| 156 | + |
| 157 | +#endif /* !_KOS_FD_H */ |
0 commit comments