Skip to content

Commit 0b048fb

Browse files
committed
New libc header <kos/fd.h>
Exposes some convenience wrappers around various kos-specific ioctls from `<kos/ioctl/fd.h>` and `<kos/ioctl/file.h>`
1 parent d6388f4 commit 0b048fb

File tree

14 files changed

+993
-61
lines changed

14 files changed

+993
-61
lines changed

kos/include/i386-kos/crt-features/crt-kos32.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3317,6 +3317,13 @@
33173317
#define __CRT_HAVE_fcntl
33183318
#define __CRT_HAVE_fcvt
33193319
#define __CRT_HAVE_fcvt_r
3320+
#define __CRT_HAVE_fd_cast
3321+
#define __CRT_HAVE_fd_delregion
3322+
#define __CRT_HAVE_fd_msalign
3323+
#define __CRT_HAVE_fd_polltest
3324+
#define __CRT_HAVE_fd_subregion
3325+
#define __CRT_HAVE_fd_tailread
3326+
#define __CRT_HAVE_fd_trim
33203327
#define __CRT_HAVE_fdatasync
33213328
#define __CRT_HAVE_fdclosedir
33223329
#define __CRT_HAVE_fdetach

kos/include/i386-kos/crt-features/crt-kos64.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3037,6 +3037,13 @@
30373037
#define __CRT_HAVE_fcntl
30383038
#define __CRT_HAVE_fcvt
30393039
#define __CRT_HAVE_fcvt_r
3040+
#define __CRT_HAVE_fd_cast
3041+
#define __CRT_HAVE_fd_delregion
3042+
#define __CRT_HAVE_fd_msalign
3043+
#define __CRT_HAVE_fd_polltest
3044+
#define __CRT_HAVE_fd_subregion
3045+
#define __CRT_HAVE_fd_tailread
3046+
#define __CRT_HAVE_fd_trim
30403047
#define __CRT_HAVE_fdatasync
30413048
#define __CRT_HAVE_fdclosedir
30423049
#define __CRT_HAVE_fdetach
@@ -9110,6 +9117,13 @@
91109117
#define __CRT_HAVE_KOS$fcntl
91119118
#define __CRT_HAVE_KOS$fcvt
91129119
#define __CRT_HAVE_KOS$fcvt_r
9120+
#define __CRT_HAVE_KOS$fd_cast
9121+
#define __CRT_HAVE_KOS$fd_delregion
9122+
#define __CRT_HAVE_KOS$fd_msalign
9123+
#define __CRT_HAVE_KOS$fd_polltest
9124+
#define __CRT_HAVE_KOS$fd_subregion
9125+
#define __CRT_HAVE_KOS$fd_tailread
9126+
#define __CRT_HAVE_KOS$fd_trim
91139127
#define __CRT_HAVE_KOS$fdatasync
91149128
#define __CRT_HAVE_KOS$fdclosedir
91159129
#define __CRT_HAVE_KOS$fdetach
@@ -13979,6 +13993,13 @@
1397913993
#define __CRT_HAVE_DOS$fcntl
1398013994
#define __CRT_HAVE_DOS$fcvt
1398113995
#define __CRT_HAVE_DOS$fcvt_r
13996+
#define __CRT_HAVE_DOS$fd_cast
13997+
#define __CRT_HAVE_DOS$fd_delregion
13998+
#define __CRT_HAVE_DOS$fd_msalign
13999+
#define __CRT_HAVE_DOS$fd_polltest
14000+
#define __CRT_HAVE_DOS$fd_subregion
14001+
#define __CRT_HAVE_DOS$fd_tailread
14002+
#define __CRT_HAVE_DOS$fd_trim
1398214003
#define __CRT_HAVE_DOS$fdatasync
1398314004
#define __CRT_HAVE_DOS$fdclosedir
1398414005
#define __CRT_HAVE_DOS$fdetach

kos/include/kos/fd.h

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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 */

kos/src/kernel/core/memory/mman/mfile-subregion.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,6 @@ mfile_subregion_create(struct mfile *__restrict self,
399399
THROWS(E_BADALLOC, E_ILLEGAL_OPERATION) {
400400
REF struct subregion_mfile *result;
401401

402-
/* Assert that "self" supports "raw" I/O */
403-
if (!mfile_hasrawio(self)) {
404-
THROW(E_ILLEGAL_OPERATION,
405-
E_ILLEGAL_OPERATION_CONTEXT_SUBREGION_NOT_POSSIBLE);
406-
}
407402
/* Assert that "self" supports "raw" I/O */
408403
if (!mfile_hasrawio(self)) {
409404
THROW(E_ILLEGAL_OPERATION,
@@ -517,7 +512,7 @@ mfile_subregion(struct mfile *__restrict self,
517512
if (!OVERFLOW_UADD(self_size, PAGEMASK, &self_size)) {
518513
self_size &= ~PAGEMASK;
519514
if (maxaddr >= self_size) {
520-
THROW(E_ILLEGAL_OPERATION,
515+
THROW(E_INVALID_OPERATION,
521516
E_ILLEGAL_OPERATION_CONTEXT_MMAP_BEYOND_END_OF_FILE,
522517
(uint32_t)maxaddr, (uint32_t)(maxaddr >> 32),
523518
(uint32_t)self_size, (uint32_t)(self_size >> 32));

0 commit comments

Comments
 (0)