hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 2321e5fad1032e670532f7aed9ec95009440a554
parent 4a2ea5b8c4cf6fa8c9b4df242f6f4a56dd65884c
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue,  2 Feb 2021 22:33:12 -0500

os: pass io::mode along to fdstream

Also updates fdopen to reuse static_fdopen and reduce
duplication/sources of truth for stream initialization.

Diffstat:
Mos/+linux/fdstream.ha | 46++++++++++++++++++++++------------------------
Mos/+linux/open.ha | 3+--
Mos/+linux/stdfd.ha | 6+++---
3 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/os/+linux/fdstream.ha b/os/+linux/fdstream.ha @@ -8,23 +8,34 @@ type fd_stream = struct { offs: size, }; -// Opens a Unix file descriptor as an io::stream. If 'name' is an empty string, -// a name will be generated based on the file descriptor number. -export fn fdopen(fd: int, name: str) *io::stream = { - // TODO: consider making the caller specify what subset of operations - // should be supported - let stream = alloc(*fd_stream, fd_stream { +fn static_fdopen( + fd: int, name: str, mode: io::mode, stream: *fd_stream, +) *io::stream = { + *stream = fd_stream { stream = io::stream { - name = strings::dup(name), - reader = &fd_read, - writer = &fd_write, - closer = &fd_close, + name = name, + closer = &fd_close_static, copier = &fd_copy, ... }, fd = fd, offs = 0z, - }); + }; + if (mode == io::mode::RDONLY || mode == io::mode::RDWR) { + stream.stream.reader = &fd_read; + }; + if (mode == io::mode::WRONLY || mode == io::mode::RDWR) { + stream.stream.writer = &fd_write; + }; + return &stream.stream; +}; + +// Opens a Unix file descriptor as an io::stream. If 'name' is an empty string, +// a name will be generated based on the file descriptor number. +export fn fdopen(fd: int, name: str, mode: io::mode) *io::stream = { + let stream = alloc(*fd_stream, fd_stream { ... }); + static_fdopen(fd, name, mode, stream); + stream.stream.closer = &fd_close; return &stream.stream; }; @@ -46,19 +57,6 @@ export fn streamfd(s: *io::stream) (int | void) = { return stream.fd; }; -fn static_fdopen(fd: int, name: str, stream: *fd_stream) *io::stream = { - stream.stream = io::stream { - name = name, - reader = &fd_read, - writer = &fd_write, - closer = &fd_close_static, - copier = &fd_copy, - ... - }; - stream.fd = fd; - return &stream.stream; -}; - fn fd_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = { let stream = s: *fd_stream; let r = rt::read(stream.fd, buf: *[*]u8, len(buf)); diff --git a/os/+linux/open.ha b/os/+linux/open.ha @@ -54,6 +54,5 @@ export fn open( n: size => n: int, }; - // TODO: Pass stream mode to fd_stream - return fdopen(fd, name); + return fdopen(fd, name, mode); }; diff --git a/os/+linux/stdfd.ha b/os/+linux/stdfd.ha @@ -5,7 +5,7 @@ let static_stdout: fd_stream = fd_stream { ... }; let static_stderr: fd_stream = fd_stream { ... }; @init fn init_stdfd() void = { - stdin = static_fdopen(0, "<stdin>", &static_stdin); - stdout = static_fdopen(1, "<stdout>", &static_stdout); - stderr = static_fdopen(2, "<stderr>", &static_stderr); + stdin = static_fdopen(0, "<stdin>", io::mode::RDONLY, &static_stdin); + stdout = static_fdopen(1, "<stdout>", io::mode::WRONLY, &static_stdout); + stderr = static_fdopen(2, "<stderr>", io::mode::WRONLY, &static_stderr); };