hare

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

commit 780129f378121fbad5d03fedd354d53513738b24
parent 1245daa29f78a8d711abd294336896ca46a283ce
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat,  4 Sep 2021 09:52:05 +0200

os: use stack allocation on fdopen

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mbufio/buffered.ha | 3++-
Mhare/module/scan.ha | 1-
Mnet/+linux.ha | 5+++--
Mnet/tcp/+linux.ha | 4++--
Mnet/udp/+linux.ha | 4++--
Mnet/unix/+linux.ha | 4++--
Mos/+linux/dirfdfs.ha | 10+++++++++-
Mos/+linux/fdstream.ha | 29++++-------------------------
Mos/+linux/stdfd.ha | 9++++++---
9 files changed, 30 insertions(+), 39 deletions(-)

diff --git a/bufio/buffered.ha b/bufio/buffered.ha @@ -53,11 +53,12 @@ export fn static_buffered( name = src.name, closer = &buffered_close_static, unwrap = &buffered_unwrap, + ... }, source = src, rbuffer = rbuf, wbuffer = wbuf, - flush = flush_default, + flush = flush_default, ... }; if (len(rbuf) != 0) { diff --git a/hare/module/scan.ha b/hare/module/scan.ha @@ -317,7 +317,6 @@ fn scan_file( hash::write(&sha, strings::toutf8(path)); let tee = io::tee(f, &sha); - let lexer = lex::init(&tee, path); let imports = parse::imports(&lexer)?; for (let i = 0z; i < len(imports); i += 1) { diff --git a/net/+linux.ha b/net/+linux.ha @@ -30,8 +30,9 @@ export fn stream_accept(l: *listener) (*io::stream | error) = { }; static let namebuf: [32]u8 = [0...]; - return os::fdopen(fd, fmt::bsprintf(namebuf, "<net connection {}>", fd), - io::mode::READ | io::mode::WRITE); + return alloc(os::fdopen(fd, + fmt::bsprintf(namebuf, "<net connection {}>", fd), + io::mode::READ | io::mode::WRITE)); }; export fn stream_shutdown(l: *listener) void = { diff --git a/net/tcp/+linux.ha b/net/tcp/+linux.ha @@ -32,8 +32,8 @@ export fn connect( err: rt::errno => return errors::errno(err), int => void, }; - return os::fdopen(sockfd, ip::string(addr), - io::mode::READ | io::mode::WRITE); + return alloc(os::fdopen(sockfd, ip::string(addr), + io::mode::READ | io::mode::WRITE)); }; // Binds a TCP listener to the given address. diff --git a/net/udp/+linux.ha b/net/udp/+linux.ha @@ -37,8 +37,8 @@ export fn sockfd(sock: socket) int = sock; // being able to receive the sender address. Only meaningful if the socket was // created with [[connect]]. export fn stream(sock: socket) *io::stream = { - return os::fdopen(sock, "<UDP stream>", - io::mode::READ | io::mode::WRITE); + return alloc(os::fdopen(sock, "<UDP stream>", + io::mode::READ | io::mode::WRITE)); }; // Obtains a [[socket]] for a given [[io::stream]], or returns void if it is not diff --git a/net/unix/+linux.ha b/net/unix/+linux.ha @@ -27,9 +27,9 @@ export fn connect(addr: addr) (*io::stream | net::error) = { int => void, }; static let buf: [rt::UNIX_PATH_MAX + 32]u8 = [0...]; - return os::fdopen(sockfd, + return alloc(os::fdopen(sockfd, fmt::bsprintf(buf, "<unix connection {}>", addr), - io::mode::READ | io::mode::WRITE); + io::mode::READ | io::mode::WRITE)); }; // Binds a UNIX socket listener to the given path. diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha @@ -146,7 +146,15 @@ fn _fs_open( fd: int => fd, }; - return fdopen(fd, path, mode); + // XXX: It would be nice to get rid of this allocation, if possible. + let file = alloc(fdopen(fd, path, mode)); + file.closer = &_fs_file_close; + return file; +}; + +fn _fs_file_close(s: *io::stream) void = { + fd_close(s); + free(s); }; fn fs_open( diff --git a/os/+linux/fdstream.ha b/os/+linux/fdstream.ha @@ -9,22 +9,10 @@ export type fdstream = struct { }; // Opens a Unix file descriptor as an io::stream. -export fn fdopen(fd: int, name: str, mode: io::mode) *io::stream = { - let stream = alloc(fdstream { ... }); - static_fdopen(fd, strings::dup(name), mode, stream); - stream.closer = &fd_close; - return stream; -}; - -fn static_fdopen( - fd: int, - name: str, - mode: io::mode, - stream: *fdstream, -) *io::stream = { - *stream = fdstream { - name = name, - closer = &fd_close_static, +export fn fdopen(fd: int, name: str, mode: io::mode) fdstream = { + let stream = fdstream { + name = name, + closer = &fd_close, copier = &fd_copy, seeker = &fd_seek, fd = fd, @@ -43,7 +31,6 @@ fn is_fdstream(s: *io::stream) bool = { return s.reader == &fd_read || s.writer == &fd_write || s.closer == &fd_close - || s.closer == &fd_close_static || s.copier == &fd_copy; }; @@ -90,14 +77,6 @@ fn fd_write(s: *io::stream, buf: const []u8) (size | io::error) = { fn fd_close(s: *io::stream) void = { let stream = s: *fdstream; rt::close(stream.fd)!; - free(s.name); - free(stream); -}; - -fn fd_close_static(s: *io::stream) void = { - let stream = s: *fdstream; - rt::close(stream.fd)!; - free(stream); }; def SENDFILE_MAX: size = 2147479552z; diff --git a/os/+linux/stdfd.ha b/os/+linux/stdfd.ha @@ -12,9 +12,12 @@ let static_stdout_bufio: bufio::bufstream = bufio::bufstream { ... }; export def BUFSIZ: size = 4096; // 4 KiB @init fn init_stdfd() void = { - stdin = static_fdopen(0, "<stdin>", io::mode::READ, &static_stdin_fd); - stdout = static_fdopen(1, "<stdout>", io::mode::WRITE, &static_stdout_fd); - stderr = static_fdopen(2, "<stderr>", io::mode::WRITE, &static_stderr_fd); + static_stdin_fd = fdopen(0, "<stdin>", io::mode::READ); + static_stdout_fd = fdopen(1, "<stdout>", io::mode::WRITE); + static_stderr_fd = fdopen(2, "<stderr>", io::mode::WRITE); + stdin = &static_stdin_fd; + stdout = &static_stdout_fd; + stderr = &static_stderr_fd; static let stdinbuf: [BUFSIZ]u8 = [0...]; stdin = bufio::static_buffered(stdin, stdinbuf, [], &static_stdin_bufio);