hare

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

commit 1acd233098dcb406b457ee55b8ddc81c0eff942b
parent e6b59a2ce3a9a835ac598d57844ec87d070fe40a
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 20 Nov 2024 09:37:33 +0100

os: add fcntl F_GETFL/F_SETFL wrappers

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

Diffstat:
Mmakefiles/freebsd.aarch64.mk | 2+-
Mmakefiles/freebsd.riscv64.mk | 2+-
Mmakefiles/freebsd.x86_64.mk | 2+-
Mmakefiles/linux.aarch64.mk | 2+-
Mmakefiles/linux.riscv64.mk | 2+-
Mmakefiles/linux.x86_64.mk | 2+-
Mmakefiles/netbsd.aarch64.mk | 2+-
Mmakefiles/netbsd.riscv64.mk | 2+-
Mmakefiles/netbsd.x86_64.mk | 2+-
Mmakefiles/openbsd.aarch64.mk | 2+-
Mmakefiles/openbsd.riscv64.mk | 2+-
Mmakefiles/openbsd.x86_64.mk | 2+-
Mos/+freebsd/dirfdfs.ha | 44++++++++++++++++++++++++++++++++++++++++++++
Aos/+freebsd/fcntl.ha | 30++++++++++++++++++++++++++++++
Aos/+linux/fcntl.ha | 30++++++++++++++++++++++++++++++
Mos/+netbsd/dirfdfs.ha | 44++++++++++++++++++++++++++++++++++++++++++++
Aos/+netbsd/fcntl.ha | 30++++++++++++++++++++++++++++++
Mos/+openbsd/dirfdfs.ha | 38++++++++++++++++++++++++++++++++++++++
Aos/+openbsd/fcntl.ha | 30++++++++++++++++++++++++++++++
19 files changed, 258 insertions(+), 12 deletions(-)

diff --git a/makefiles/freebsd.aarch64.mk b/makefiles/freebsd.aarch64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+freebsd/dirfdfs.ha os/+freebsd/exit.ha os/+freebsd/fs.ha os/+freebsd/memfd.ha os/+freebsd/platform_environ.ha os/+freebsd/shm.ha os/+freebsd/status.ha os/+freebsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+freebsd/dirfdfs.ha os/+freebsd/exit.ha os/+freebsd/fcntl.ha os/+freebsd/fs.ha os/+freebsd/memfd.ha os/+freebsd/platform_environ.ha os/+freebsd/shm.ha os/+freebsd/status.ha os/+freebsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/freebsd.riscv64.mk b/makefiles/freebsd.riscv64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+freebsd/dirfdfs.ha os/+freebsd/exit.ha os/+freebsd/fs.ha os/+freebsd/memfd.ha os/+freebsd/platform_environ.ha os/+freebsd/shm.ha os/+freebsd/status.ha os/+freebsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+freebsd/dirfdfs.ha os/+freebsd/exit.ha os/+freebsd/fcntl.ha os/+freebsd/fs.ha os/+freebsd/memfd.ha os/+freebsd/platform_environ.ha os/+freebsd/shm.ha os/+freebsd/status.ha os/+freebsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/freebsd.x86_64.mk b/makefiles/freebsd.x86_64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+freebsd/dirfdfs.ha os/+freebsd/exit.ha os/+freebsd/fs.ha os/+freebsd/memfd.ha os/+freebsd/platform_environ.ha os/+freebsd/shm.ha os/+freebsd/status.ha os/+freebsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+freebsd/dirfdfs.ha os/+freebsd/exit.ha os/+freebsd/fcntl.ha os/+freebsd/fs.ha os/+freebsd/memfd.ha os/+freebsd/platform_environ.ha os/+freebsd/shm.ha os/+freebsd/status.ha os/+freebsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.aarch64.mk b/makefiles/linux.aarch64.mk @@ -147,7 +147,7 @@ $(HARECACHE)/fs.ssa: $(fs_ha) $(HARECACHE)/encoding_utf8.td $(HARECACHE)/errors. @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/fs.td.tmp -N fs $(fs_ha) -os_ha = os/+linux/dirfdfs.ha os/+linux/exit.ha os/+linux/fs.ha os/+linux/memfd.ha os/+linux/memory.ha os/+linux/platform_environ.ha os/+linux/shm.ha os/+linux/status.ha os/+linux/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+linux/dirfdfs.ha os/+linux/exit.ha os/+linux/fcntl.ha os/+linux/fs.ha os/+linux/memfd.ha os/+linux/memory.ha os/+linux/platform_environ.ha os/+linux/shm.ha os/+linux/status.ha os/+linux/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/math.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.riscv64.mk b/makefiles/linux.riscv64.mk @@ -147,7 +147,7 @@ $(HARECACHE)/fs.ssa: $(fs_ha) $(HARECACHE)/encoding_utf8.td $(HARECACHE)/errors. @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/fs.td.tmp -N fs $(fs_ha) -os_ha = os/+linux/dirfdfs.ha os/+linux/exit.ha os/+linux/fs.ha os/+linux/memfd.ha os/+linux/memory.ha os/+linux/platform_environ.ha os/+linux/shm.ha os/+linux/status.ha os/+linux/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+linux/dirfdfs.ha os/+linux/exit.ha os/+linux/fcntl.ha os/+linux/fs.ha os/+linux/memfd.ha os/+linux/memory.ha os/+linux/platform_environ.ha os/+linux/shm.ha os/+linux/status.ha os/+linux/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/math.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.x86_64.mk b/makefiles/linux.x86_64.mk @@ -147,7 +147,7 @@ $(HARECACHE)/fs.ssa: $(fs_ha) $(HARECACHE)/encoding_utf8.td $(HARECACHE)/errors. @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/fs.td.tmp -N fs $(fs_ha) -os_ha = os/+linux/dirfdfs.ha os/+linux/exit.ha os/+linux/fs.ha os/+linux/memfd.ha os/+linux/memory.ha os/+linux/platform_environ.ha os/+linux/shm.ha os/+linux/status.ha os/+linux/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+linux/dirfdfs.ha os/+linux/exit.ha os/+linux/fcntl.ha os/+linux/fs.ha os/+linux/memfd.ha os/+linux/memory.ha os/+linux/platform_environ.ha os/+linux/shm.ha os/+linux/status.ha os/+linux/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/math.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/netbsd.aarch64.mk b/makefiles/netbsd.aarch64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fcntl.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/netbsd.riscv64.mk b/makefiles/netbsd.riscv64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fcntl.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/netbsd.x86_64.mk b/makefiles/netbsd.x86_64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fcntl.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/openbsd.aarch64.mk b/makefiles/openbsd.aarch64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+openbsd/dirfdfs.ha os/+openbsd/exit.ha os/+openbsd/fs.ha os/+openbsd/platform_environ.ha os/+openbsd/shm.ha os/+openbsd/status.ha os/+openbsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+openbsd/dirfdfs.ha os/+openbsd/exit.ha os/+openbsd/fcntl.ha os/+openbsd/fs.ha os/+openbsd/platform_environ.ha os/+openbsd/shm.ha os/+openbsd/status.ha os/+openbsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/openbsd.riscv64.mk b/makefiles/openbsd.riscv64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+openbsd/dirfdfs.ha os/+openbsd/exit.ha os/+openbsd/fs.ha os/+openbsd/platform_environ.ha os/+openbsd/shm.ha os/+openbsd/status.ha os/+openbsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+openbsd/dirfdfs.ha os/+openbsd/exit.ha os/+openbsd/fcntl.ha os/+openbsd/fs.ha os/+openbsd/platform_environ.ha os/+openbsd/shm.ha os/+openbsd/status.ha os/+openbsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/openbsd.x86_64.mk b/makefiles/openbsd.x86_64.mk @@ -129,7 +129,7 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+openbsd/dirfdfs.ha os/+openbsd/exit.ha os/+openbsd/fs.ha os/+openbsd/platform_environ.ha os/+openbsd/shm.ha os/+openbsd/status.ha os/+openbsd/stdfd.ha os/environ.ha os/os.ha +os_ha = os/+openbsd/dirfdfs.ha os/+openbsd/exit.ha os/+openbsd/fcntl.ha os/+openbsd/fs.ha os/+openbsd/platform_environ.ha os/+openbsd/shm.ha os/+openbsd/status.ha os/+openbsd/stdfd.ha os/environ.ha os/os.ha $(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/os/+freebsd/dirfdfs.ha b/os/+freebsd/dirfdfs.ha @@ -161,6 +161,50 @@ fn fsflags_to_bsd(flags: fs::flag) (int | errors::unsupported) = { return out; }; +fn bsd_to_fsflags(flags: int) fs::flag = { + let out: fs::flag = 0; + if (flags & rt::O_WRONLY == rt::O_WRONLY) { + out |= fs::flag::WRONLY; + }; + if (flags & rt::O_RDWR == rt::O_RDWR) { + out |= fs::flag::RDWR; + }; + if (flags & rt::O_CREAT == rt::O_CREAT) { + out |= fs::flag::CREATE; + }; + if (flags & rt::O_EXCL == rt::O_EXCL) { + out |= fs::flag::EXCL; + }; + if (flags & rt::O_NOCTTY == 0) { + out |= fs::flag::CTTY; + }; + if (flags & rt::O_TRUNC == rt::O_TRUNC) { + out |= fs::flag::TRUNC; + }; + if (flags & rt::O_APPEND == rt::O_APPEND) { + out |= fs::flag::APPEND; + }; + if (flags & rt::O_NONBLOCK == rt::O_NONBLOCK) { + out |= fs::flag::NONBLOCK; + }; + if (flags & rt::O_DSYNC == rt::O_DSYNC) { + out |= fs::flag::DSYNC; + }; + if (flags & rt::O_SYNC == rt::O_SYNC) { + out |= fs::flag::SYNC; + }; + if (flags & rt::O_DIRECTORY == rt::O_DIRECTORY) { + out |= fs::flag::DIRECTORY; + }; + if (flags & rt::O_NOFOLLOW == rt::O_NOFOLLOW) { + out |= fs::flag::NOFOLLOW; + }; + if (flags & rt::O_CLOEXEC == 0) { + out |= fs::flag::NOCLOEXEC; + }; + return out; +}; + fn fs_open_file( fs: *fs::fs, path: str, diff --git a/os/+freebsd/fcntl.ha b/os/+freebsd/fcntl.ha @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use errors; +use fs; +use io; +use rt; + +// Returns the [[fs::flag]]s associated with a file descriptor. See fcntl(2). +export fn getfl(file: io::file) (fs::flag | errors::error) = { + match (rt::fcntl(file, rt::F_GETFL, void)) { + case let i: int => + return bsd_to_fsflags(i); + case let err: rt::errno => + return errors::errno(err); + }; +}; + +// Sets the [[fs::flag]]s associated with a file descriptor. Changes to the +// access mode (e.g. [[fs::flag::RDWR]] and file creation flags (e.g. +// [[fs::flag::CREATE]]) are ignored. See fcntl(2). +export fn setfl(file: io::file, flags: fs::flag) (void | errors::error) = { + const flags = fsflags_to_bsd(flags)?; + match (rt::fcntl(file, rt::F_SETFL, flags)) { + case int => + return; + case let err: rt::errno => + return errors::errno(err); + }; +}; diff --git a/os/+linux/fcntl.ha b/os/+linux/fcntl.ha @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use errors; +use fs; +use io; +use rt; + +// Returns the [[fs::flag]]s associated with a file descriptor. See fcntl(2), +// ref F_GETFL. +export fn getflags(file: io::file) (fs::flag | errors::error) = { + match (rt::fcntl(file, rt::F_GETFL, void)) { + case let i: int => + return i: fs::flag; + case let err: rt::errno => + return errors::errno(err); + }; +}; + +// Sets the [[fs::flag]]s associated with a file descriptor. Changes to the +// access mode (e.g. [[fs::flag::RDWR]] and file creation flags (e.g. +// [[fs::flag::CREATE]]) are ignored. See fcntl(2), ref F_SETFL. +export fn setflags(file: io::file, flags: fs::flag) (void | errors::error) = { + match (rt::fcntl(file, rt::F_SETFL, flags)) { + case int => + return; + case let err: rt::errno => + return errors::errno(err); + }; +}; diff --git a/os/+netbsd/dirfdfs.ha b/os/+netbsd/dirfdfs.ha @@ -161,6 +161,50 @@ fn fsflags_to_bsd(flags: fs::flag) (int | errors::unsupported) = { return out; }; +fn bsd_to_fsflags(flags: int) fs::flag = { + let out: fs::flag = 0; + if (flags & rt::O_WRONLY == rt::O_WRONLY) { + out |= fs::flag::WRONLY; + }; + if (flags & rt::O_RDWR == rt::O_RDWR) { + out |= fs::flag::RDWR; + }; + if (flags & rt::O_CREAT == rt::O_CREAT) { + out |= fs::flag::CREATE; + }; + if (flags & rt::O_EXCL == rt::O_EXCL) { + out |= fs::flag::EXCL; + }; + if (flags & rt::O_NOCTTY == 0) { + out |= fs::flag::CTTY; + }; + if (flags & rt::O_TRUNC == rt::O_TRUNC) { + out |= fs::flag::TRUNC; + }; + if (flags & rt::O_APPEND == rt::O_APPEND) { + out |= fs::flag::APPEND; + }; + if (flags & rt::O_NONBLOCK == rt::O_NONBLOCK) { + out |= fs::flag::NONBLOCK; + }; + if (flags & rt::O_DSYNC == rt::O_DSYNC) { + out |= fs::flag::DSYNC; + }; + if (flags & rt::O_SYNC == rt::O_SYNC) { + out |= fs::flag::SYNC; + }; + if (flags & rt::O_DIRECTORY == rt::O_DIRECTORY) { + out |= fs::flag::DIRECTORY; + }; + if (flags & rt::O_NOFOLLOW == rt::O_NOFOLLOW) { + out |= fs::flag::NOFOLLOW; + }; + if (flags & rt::O_CLOEXEC == 0) { + out |= fs::flag::NOCLOEXEC; + }; + return out; +}; + fn fs_open_file( fs: *fs::fs, path: str, diff --git a/os/+netbsd/fcntl.ha b/os/+netbsd/fcntl.ha @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use errors; +use fs; +use io; +use rt; + +// Returns the [[fs::flag]]s associated with a file descriptor. See fcntl(2). +export fn getfl(file: io::file) (fs::flag | errors::error) = { + match (rt::fcntl(file, rt::F_GETFL, void)) { + case let i: int => + return bsd_to_fsflags(i); + case let err: rt::errno => + return errors::errno(err); + }; +}; + +// Sets the [[fs::flag]]s associated with a file descriptor. Changes to the +// access mode (e.g. [[fs::flag::RDWR]] and file creation flags (e.g. +// [[fs::flag::CREATE]]) are ignored. See fcntl(2). +export fn setfl(file: io::file, flags: fs::flag) (void | errors::error) = { + const flags = fsflags_to_bsd(flags)?; + match (rt::fcntl(file, rt::F_SETFL, flags)) { + case int => + return; + case let err: rt::errno => + return errors::errno(err); + }; +}; diff --git a/os/+openbsd/dirfdfs.ha b/os/+openbsd/dirfdfs.ha @@ -65,6 +65,44 @@ fn fsflags_to_bsd(flags: fs::flag) (int | errors::unsupported) = { return out; }; +fn bsd_to_fsflags(flags: int) fs::flag = { + let out: fs::flag = 0; + if (flags & rt::O_WRONLY == rt::O_WRONLY) { + out |= fs::flag::WRONLY; + }; + if (flags & rt::O_RDWR == rt::O_RDWR) { + out |= fs::flag::RDWR; + }; + if (flags & rt::O_CREAT == rt::O_CREAT) { + out |= fs::flag::CREATE; + }; + if (flags & rt::O_EXCL == rt::O_EXCL) { + out |= fs::flag::EXCL; + }; + if (flags & rt::O_TRUNC == rt::O_TRUNC) { + out |= fs::flag::TRUNC; + }; + if (flags & rt::O_APPEND == rt::O_APPEND) { + out |= fs::flag::APPEND; + }; + if (flags & rt::O_NONBLOCK == rt::O_NONBLOCK) { + out |= fs::flag::NONBLOCK; + }; + if (flags & rt::O_SYNC == rt::O_SYNC) { + out |= fs::flag::SYNC; + }; + if (flags & rt::O_DIRECTORY == rt::O_DIRECTORY) { + out |= fs::flag::DIRECTORY; + }; + if (flags & rt::O_NOFOLLOW == rt::O_NOFOLLOW) { + out |= fs::flag::NOFOLLOW; + }; + if (flags & rt::O_CLOEXEC == 0) { + out |= fs::flag::NOCLOEXEC; + }; + return out; +}; + fn _fs_open( fs: *fs::fs, path: str, diff --git a/os/+openbsd/fcntl.ha b/os/+openbsd/fcntl.ha @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use errors; +use fs; +use io; +use rt; + +// Returns the [[fs::flag]]s associated with a file descriptor. See fcntl(2). +export fn getfl(file: io::file) (fs::flag | errors::error) = { + match (rt::fcntl(file, rt::F_GETFL, void)) { + case let i: int => + return bsd_to_fsflags(i); + case let err: rt::errno => + return errors::errno(err); + }; +}; + +// Sets the [[fs::flag]]s associated with a file descriptor. Changes to the +// access mode (e.g. [[fs::flag::RDWR]] and file creation flags (e.g. +// [[fs::flag::CREATE]]) are ignored. See fcntl(2). +export fn setfl(file: io::file, flags: fs::flag) (void | errors::error) = { + const flags = fsflags_to_bsd(flags)?; + match (rt::fcntl(file, rt::F_SETFL, flags)) { + case int => + return; + case let err: rt::errno => + return errors::errno(err); + }; +};