commit 35a043544169a5f1db3c598b376ccf47436682de
parent 548181245409811ed56bff19def827b87236f5c0
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 22 Oct 2021 10:53:40 +0200
iobus: add open, create
These seem to be buggy, not sure what's up.
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/iobus/io_uring/ops.ha b/iobus/io_uring/ops.ha
@@ -1,7 +1,10 @@
+use fs;
use io;
use linux::io_uring;
use net::ip;
+use os;
use rt;
+use strings;
use unix::poll;
// TODO: Seek to de-duplicate more of the SQE prep code
@@ -172,10 +175,88 @@ export fn poll(
return handle { sqe = sqe, ... };
};
+// Returns the revents for a [[poll]] operation.
export fn endpoll(bus: *bus, res: result) (poll::event | error) = {
let handle = handleof(res);
- assert(handle.sqe.opcode == io_uring::op::POLL_ADD);
+ assert(handle.sqe.opcode == io_uring::op::POLL_ADD,
+ "endpoll called for non-poll iobus::result");
return cqe_result(res)?: poll::event;
};
// TODO: poll_remove
+
+// If no flags are provided, [[fs::flags::RDONLY]], [[fs::flags::NOCTTY]],
+// [[fs::flags::CLOEXEC]] are used when opening the file. If you pass your own
+// flags, it is recommended that you add the latter two unless you know that you
+// do not want them.
+export fn open(
+ bus: *bus,
+ path: str,
+ flags: fs::flags...
+) (handle | queuefull) = {
+ let sqe = getsqe(bus)?;
+ let handle = handle {
+ sqe = sqe,
+ cstring = strings::to_c(path),
+ ...
+ };
+ let oflags = 0;
+ if (len(flags) == 0z) {
+ oflags |= (fs::flags::NOCTTY
+ | fs::flags::CLOEXEC
+ | fs::flags::RDONLY): int;
+ };
+ for (let i = 0z; i < len(flags); i += 1z) {
+ oflags |= flags[i]: int;
+ };
+ io_uring::openat(sqe, os::dirfile(os::cwd), handle.cstring, oflags, 0);
+ return handle;
+};
+
+// Returns the new file handle from an [[open]] operation.
+export fn endopen(bus: *bus, res: result) (io::file | error) = {
+ let handle = handleof(res);
+ assert(handle.sqe.opcode == io_uring::op::OPENAT,
+ "endopen called for non-poll iobus::result");
+ free(handle.cstring);
+ return cqe_result(res)?: io::file;
+};
+
+// If no flags are provided, [[fs::flags::WRONLY]], [[fs::flags::NOCTTY]],
+// [[fs::flags::CLOEXEC]] are used when opening the file. If you pass your own
+// flags, it is recommended that you add the latter two unless you know that you
+// do not want them.
+export fn create(
+ bus: *bus,
+ path: str,
+ mode: fs::mode,
+ flags: fs::flags...
+) (handle | queuefull) = {
+ let sqe = getsqe(bus)?;
+ let oflags = 0;
+ if (len(flags) == 0z) {
+ oflags |= (fs::flags::NOCTTY
+ | fs::flags::CLOEXEC
+ | fs::flags::WRONLY): int;
+ };
+ for (let i = 0z; i < len(flags); i += 1z) {
+ oflags |= flags[i]: int;
+ };
+ oflags |= fs::flags::CREATE: int;
+ let handle = handle {
+ sqe = sqe,
+ cstring = strings::to_c(path),
+ ...
+ };
+ io_uring::openat(sqe, os::dirfile(os::cwd), handle.cstring, oflags, mode);
+ return handle;
+};
+
+// Returns the new file handle from an [[create]] operation.
+export fn endcreate(bus: *bus, res: result) (io::file | error) = {
+ let handle = handleof(res);
+ assert(handle.sqe.opcode == io_uring::op::OPENAT,
+ "endcreate called for non-poll iobus::result");
+ free(handle.cstring);
+ return cqe_result(res)?: io::file;
+};
diff --git a/iobus/io_uring/types.ha b/iobus/io_uring/types.ha
@@ -53,6 +53,7 @@ export type handle = struct {
callbacks: [](*fn(res: result, data: *void) void, *void),
union {
accept: accept_handle,
+ cstring: *char,
},
};