commit 140cdef5dff9565b0a9828b8a0d6688bb19996db
parent ee84a84873a304f7848b78b9d4aebfa75f80643f
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 1 Feb 2021 10:08:50 -0500
os: add os::open
Diffstat:
4 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/os/+linux/fdstream.ha b/os/+linux/fdstream.ha
@@ -24,6 +24,26 @@ export fn fdopen(fd: int, name: str) *io::stream = {
return &stream.stream;
};
+// Returns the file descriptor for a given [io::stream]. If there is no fd
+// associated with this stream, void is returned.
+export fn streamfd(s: *io::stream) (int | void) = {
+ if (s.reader != &fd_read) {
+ return void;
+ };
+ let stream = s: *fd_stream;
+ return stream.fd;
+};
+
+fn static_fdopen(fd: int, name: str, stream: *fd_stream) void = {
+ stream.stream = io::stream {
+ name = name,
+ reader = &fd_read,
+ writer = &fd_write,
+ closer = &fd_close,
+ };
+ stream.fd = fd;
+};
+
fn fd_read(s: *io::stream, buf: []u8) (size | io::error) = {
let stream = s: *fd_stream;
let r = rt::read(stream.fd, (&buf: *types::slice).data: *[*]u8, len(buf));
@@ -53,23 +73,3 @@ fn fd_close(s: *io::stream) void = {
rt::close(stream.fd);
free(stream);
};
-
-fn static_fdopen(fd: int, name: str, stream: *fd_stream) void = {
- stream.stream = io::stream {
- name = name,
- reader = &fd_read,
- writer = &fd_write,
- closer = &fd_close,
- };
- stream.fd = fd;
-};
-
-// Returns the file descriptor for a given [io::stream]. If there is no fd
-// associated with this stream, void is returned.
-export fn streamfd(s: *io::stream) (int | void) = {
- if (s.reader != &fd_read) {
- return void;
- };
- let stream = s: *fd_stream;
- return stream.fd;
-};
diff --git a/os/+linux/open.ha b/os/+linux/open.ha
@@ -0,0 +1,29 @@
+use io;
+use rt;
+use strings;
+
+export fn open(path: (str | []u8), mode: io::mode) (*io::stream | io::error) = {
+ // Verify that these line up with the Linux ABI:
+ static assert(io::mode::RDONLY: uint == 0u);
+ static assert(io::mode::WRONLY: uint == 1u);
+ static assert(io::mode::RDWR: uint == 2u);
+
+ const p: []u8 = match (path) {
+ s: str => strings::to_utf8(s),
+ b: []u8 => b,
+ };
+ const name: str = match (path) {
+ s: str => s,
+ b: []u8 => "<open([]u8)>", // TODO: try to decode it?
+ };
+
+ // TODO: Cast slice to array
+ let r = rt::open((&p: *types::slice).data: *const char, mode: int, 0u);
+ let fd: int = match (rt::wrap_return(r)) {
+ err: rt::errno => return errno_to_io(err),
+ n: size => n: int,
+ };
+
+ // TODO: Pass mode flags along to fd_stream
+ return fdopen(fd, name);
+};
diff --git a/rt/+linux/abort.ha b/rt/+linux/abort.ha
@@ -7,7 +7,7 @@ export @noreturn @symbol("rt.abort") fn _abort(msg: str) void = {
};
// See harec:include/gen.h
-const reasons: [3]str = [
+const reasons: [_]str = [
"slice or array access out of bounds", // 0
"type assertion failed", // 1
"out of memory", // 2
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -6,14 +6,17 @@ fn syscall4(u64, u64, u64, u64, u64) u64;
fn syscall5(u64, u64, u64, u64, u64, u64) u64;
fn syscall6(u64, u64, u64, u64, u64, u64, u64) u64;
-export fn close(fd: int) int = syscall1(SYS_close, fd: u64): int;
-
export fn read(fd: int, buf: *void, count: size) size =
syscall3(SYS_read, fd: u64, buf: uintptr: u64, count: u64): size;
export fn write(fd: int, buf: *const void, count: size) size =
syscall3(SYS_write, fd: u64, buf: uintptr: u64, count: u64): size;
+export fn open(path: *const char, flags: int, mode: uint) size =
+ syscall3(SYS_open, path: uintptr: u64, flags: u64, mode: u64): size;
+
+export fn close(fd: int) int = syscall1(SYS_close, fd: u64): int;
+
export fn getpid() int = syscall0(SYS_getpid): int;
export @noreturn fn exit(status: int) void = syscall1(SYS_exit, status: u64);