hare

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

commit 635eeda5b00835b94c5b696df140e8bf28c53134
parent e74074f9142efdbb3abd9ff562fe6b123fdc6390
Author: Sebastian <sebastian@sebsite.pw>
Date:   Tue, 17 Jan 2023 01:04:18 -0500

os: make stderr a handle instead of a file

Previously, stdin and stdout were handles, since they were really bufio
streams. Since stderr is unbuffered, it was just an io::file. This
commit makes stderr an io::handle, and adds stderr_file as an io::file.
stderr is still unbuffered; the handle is really the same as the file.
Besides just for consistency with the other streams, this change allows
all standard handles to be mutated into a different stream at runtime.
This is done by the new test runner to capture the output of tests, by
temporarily changing the value of os::stdout and os::stderr to a
bufio::dynamic stream.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mcmd/hare/plan.ha | 5+++--
Mcmd/hare/release.ha | 6+++---
Mos/+freebsd/stdfd.ha | 7+++++--
Mos/+linux/stdfd.ha | 7+++++--
Mos/exec/cmd.ha | 4++--
5 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/cmd/hare/plan.ha b/cmd/hare/plan.ha @@ -123,7 +123,8 @@ fn mkplan( libdir = libdir, libs = libs, progress = plan_progress { - tty = if (tty::isatty(os::stderr)) os::stderr else void, + tty = if (tty::isatty(os::stderr_file)) os::stderr_file + else void, ... }, ... @@ -277,7 +278,7 @@ fn execute( const pipe = if (plan.progress.tty is io::file) { const pipe = exec::pipe(); - exec::addfile(&cmd, os::stderr, pipe.1); + exec::addfile(&cmd, os::stderr_file, pipe.1); yield pipe; } else (0: io::file, 0: io::file); diff --git a/cmd/hare/release.ha b/cmd/hare/release.ha @@ -306,7 +306,7 @@ fn signtag(tmpdir: str, name: str, tag: str, key: str) (void | release_error) = // TODO: It might be better to capture this and print it to stderr // ourselves if ssh-keygen exits nonzero, so that the error details are // available to the user for diagnosis. - exec::addfile(&ssh, os::stderr, exec::nullfd); + exec::addfile(&ssh, os::stderr_file, exec::nullfd); const pipe1 = exec::pipe(); const pipe2 = exec::pipe(); @@ -328,7 +328,7 @@ fn signtag(tmpdir: str, name: str, tag: str, key: str) (void | release_error) = fn git_runcmd(args: str...) (void | release_error) = { const cmd = exec::cmd("git", args...)?; - exec::addfile(&cmd, os::stderr, exec::nullfd); + exec::addfile(&cmd, os::stderr_file, exec::nullfd); const proc = exec::start(&cmd)?; const status = exec::wait(&proc)?; return exec::check(&status)?; @@ -339,7 +339,7 @@ fn git_readcmd(args: str...) (str | release_error) = { defer io::close(pipe.0)!; const cmd = exec::cmd("git", args...)?; exec::addfile(&cmd, os::stdout_file, pipe.1); - exec::addfile(&cmd, os::stderr, exec::nullfd); + exec::addfile(&cmd, os::stderr_file, exec::nullfd); const proc = exec::start(&cmd)?; io::close(pipe.1)?; const result = io::drain(pipe.0)?; diff --git a/os/+freebsd/stdfd.ha b/os/+freebsd/stdfd.ha @@ -27,8 +27,11 @@ export let stdout: io::handle = rt::STDOUT_FILENO; // initialized by init_stdfd // The standard output, as an [[io::file]]. This handle is unbuffered. export let stdout_file: io::file = rt::STDOUT_FILENO; -// The standard error. -export let stderr: io::file = rt::STDERR_FILENO; +// The standard error. This handle is unbuffered. +export let stderr: io::handle = rt::STDERR_FILENO; + +// The standard error, as an [[io::file]]. This handle is unbuffered. +export let stderr_file: io::file = rt::STDERR_FILENO; // The recommended buffer size for reading from disk. export def BUFSIZ: size = 4096; // 4 KiB diff --git a/os/+linux/stdfd.ha b/os/+linux/stdfd.ha @@ -31,8 +31,11 @@ export let stdout: io::handle = rt::STDOUT_FILENO; // initialized by init_stdfd // The standard output, as an [[io::file]]. This handle is unbuffered. export let stdout_file: io::file = rt::STDOUT_FILENO; -// The standard error. -export let stderr: io::file = rt::STDERR_FILENO; +// The standard error. This handle is unbuffered. +export let stderr: io::handle = rt::STDERR_FILENO; + +// The standard error, as an [[io::file]]. This handle is unbuffered. +export let stderr_file: io::file = rt::STDERR_FILENO; // The recommended buffer size for reading from disk. export def BUFSIZ: size = 4096; // 4 KiB diff --git a/os/exec/cmd.ha b/os/exec/cmd.ha @@ -166,7 +166,7 @@ export fn addfile( export fn closestd(cmd: *command) void = { addfile(cmd, os::stdin_file, closefd); addfile(cmd, os::stdout_file, closefd); - addfile(cmd, os::stderr, closefd); + addfile(cmd, os::stderr_file, closefd); }; // Redirects all standard files (stdin, stdout, and stderr) to /dev/null or the @@ -174,7 +174,7 @@ export fn closestd(cmd: *command) void = { export fn nullstd(cmd: *command) void = { addfile(cmd, os::stdin_file, nullfd); addfile(cmd, os::stdout_file, nullfd); - addfile(cmd, os::stderr, nullfd); + addfile(cmd, os::stderr_file, nullfd); }; // Configures the child process's working directory. This does not affect the