hare

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

commit 255d5f785bf75ede677d6c1e318f18619a975261
parent a96bd0449c2beb92590c7eea17046498e43853d2
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 10 Nov 2023 13:56:51 +0100

io: add dup, dup2 functions

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

Diffstat:
Aio/+freebsd/dup.ha | 44++++++++++++++++++++++++++++++++++++++++++++
Aio/+linux/dup.ha | 42++++++++++++++++++++++++++++++++++++++++++
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+-
8 files changed, 92 insertions(+), 6 deletions(-)

diff --git a/io/+freebsd/dup.ha b/io/+freebsd/dup.ha @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use errors; +use rt; + +// Flags for [[dup]] and [[dup2]] operations. +export type dupflag = enum { + NONE = 0, + + // Causes [[dup]] and [[dup2]] not to set the CLOEXEC flag on the + // duplicated file descriptor. By default, CLOEXEC is set. + NOCLOEXEC = rt::FD_CLOEXEC, +}; + +// Duplicates a file descriptor. +export fn dup(old: file, flags: dupflag) (file | error) = { + flags ^= dupflag::NOCLOEXEC; // Invert CLOEXEC + + match (rt::dup2(old, -1)) { + case let fd: int => + const fl = rt::fcntl(fd, rt::F_GETFD, 0)!; + rt::fcntl(fd, rt::F_SETFD, fl | rt::FD_CLOEXEC)!; + return fd; + case let e: rt::errno => + return errors::errno(e); + }; +}; + +// Duplicates a file descriptor and stores the new file at a specific file +// descriptor number. If the file indicated by "new" already refers to an open +// file, this file will be closed before the file descriptor is reused. +export fn dup2(old: file, new: file, flags: dupflag) (file | error) = { + flags ^= dupflag::NOCLOEXEC; // Invert CLOEXEC + + match (rt::dup2(old, new)) { + case let fd: int => + const fl = rt::fcntl(fd, rt::F_GETFD, 0)!; + rt::fcntl(fd, rt::F_SETFD, fl | flags)!; + return fd; + case let e: rt::errno => + return errors::errno(e); + }; +}; diff --git a/io/+linux/dup.ha b/io/+linux/dup.ha @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use errors; +use rt; + +// Flags for [[dup]] and [[dup2]] operations. +export type dupflag = enum { + NONE = 0, + + // Causes [[dup]] and [[dup2]] not to set the CLOEXEC flag on the + // duplicated file descriptor. By default, CLOEXEC is set. + NOCLOEXEC = rt::FD_CLOEXEC, +}; + +// Duplicates a file descriptor. +export fn dup(old: file, flags: dupflag) (file | error) = { + flags ^= dupflag::NOCLOEXEC; // Invert CLOEXEC + + match (rt::dup(old)) { + case let fd: int => + const fl = rt::fcntl(fd, rt::F_GETFD, 0)!; + rt::fcntl(fd, rt::F_SETFD, fl | flags)!; + return fd; + case let e: rt::errno => + return errors::errno(e); + }; +}; + +// Duplicates a file descriptor and stores the new file at a specific file +// descriptor number. If the file indicated by "new" already refers to an open +// file, this file will be closed before the file descriptor is reused. +export fn dup2(old: file, new: file, flags: dupflag) (file | error) = { + flags ^= dupflag::NOCLOEXEC; // Invert CLOEXEC + + match (rt::dup3(old, new, flags)) { + case let fd: int => + return fd; + case let e: rt::errno => + return errors::errno(e); + }; +}; diff --git a/makefiles/freebsd.aarch64.mk b/makefiles/freebsd.aarch64.mk @@ -57,7 +57,7 @@ $(HARECACHE)/errors.ssa: $(errors_ha) $(HARECACHE)/rt.td @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/errors.ssa -t $(HARECACHE)/errors.td.tmp -N errors $(errors_ha) -io_ha = io/+freebsd/mmap.ha io/+freebsd/platform_file.ha io/+freebsd/vector.ha io/arch+aarch64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha +io_ha = io/+freebsd/dup.ha io/+freebsd/mmap.ha io/+freebsd/platform_file.ha io/+freebsd/vector.ha io/arch+aarch64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha $(HARECACHE)/io.ssa: $(io_ha) $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/rt.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/freebsd.riscv64.mk b/makefiles/freebsd.riscv64.mk @@ -57,7 +57,7 @@ $(HARECACHE)/errors.ssa: $(errors_ha) $(HARECACHE)/rt.td @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/errors.ssa -t $(HARECACHE)/errors.td.tmp -N errors $(errors_ha) -io_ha = io/+freebsd/mmap.ha io/+freebsd/platform_file.ha io/+freebsd/vector.ha io/arch+riscv64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha +io_ha = io/+freebsd/dup.ha io/+freebsd/mmap.ha io/+freebsd/platform_file.ha io/+freebsd/vector.ha io/arch+riscv64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha $(HARECACHE)/io.ssa: $(io_ha) $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/rt.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/freebsd.x86_64.mk b/makefiles/freebsd.x86_64.mk @@ -57,7 +57,7 @@ $(HARECACHE)/errors.ssa: $(errors_ha) $(HARECACHE)/rt.td @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/errors.ssa -t $(HARECACHE)/errors.td.tmp -N errors $(errors_ha) -io_ha = io/+freebsd/mmap.ha io/+freebsd/platform_file.ha io/+freebsd/vector.ha io/arch+x86_64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha +io_ha = io/+freebsd/dup.ha io/+freebsd/mmap.ha io/+freebsd/platform_file.ha io/+freebsd/vector.ha io/arch+x86_64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha $(HARECACHE)/io.ssa: $(io_ha) $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/rt.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.aarch64.mk b/makefiles/linux.aarch64.mk @@ -57,7 +57,7 @@ $(HARECACHE)/errors.ssa: $(errors_ha) $(HARECACHE)/rt.td @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/errors.ssa -t $(HARECACHE)/errors.td.tmp -N errors $(errors_ha) -io_ha = io/+linux/mmap.ha io/+linux/platform_file.ha io/+linux/vector.ha io/arch+aarch64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha +io_ha = io/+linux/dup.ha io/+linux/mmap.ha io/+linux/platform_file.ha io/+linux/vector.ha io/arch+aarch64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha $(HARECACHE)/io.ssa: $(io_ha) $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/rt.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.riscv64.mk b/makefiles/linux.riscv64.mk @@ -57,7 +57,7 @@ $(HARECACHE)/errors.ssa: $(errors_ha) $(HARECACHE)/rt.td @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/errors.ssa -t $(HARECACHE)/errors.td.tmp -N errors $(errors_ha) -io_ha = io/+linux/mmap.ha io/+linux/platform_file.ha io/+linux/vector.ha io/arch+riscv64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha +io_ha = io/+linux/dup.ha io/+linux/mmap.ha io/+linux/platform_file.ha io/+linux/vector.ha io/arch+riscv64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha $(HARECACHE)/io.ssa: $(io_ha) $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/rt.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" diff --git a/makefiles/linux.x86_64.mk b/makefiles/linux.x86_64.mk @@ -57,7 +57,7 @@ $(HARECACHE)/errors.ssa: $(errors_ha) $(HARECACHE)/rt.td @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $(HARECACHE)/errors.ssa -t $(HARECACHE)/errors.td.tmp -N errors $(errors_ha) -io_ha = io/+linux/mmap.ha io/+linux/platform_file.ha io/+linux/vector.ha io/arch+x86_64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha +io_ha = io/+linux/dup.ha io/+linux/mmap.ha io/+linux/platform_file.ha io/+linux/vector.ha io/arch+x86_64.ha io/copy.ha io/drain.ha io/empty.ha io/file.ha io/handle.ha io/limit.ha io/stream.ha io/tee.ha io/types.ha io/util.ha io/zero.ha $(HARECACHE)/io.ssa: $(io_ha) $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/rt.td $(HARECACHE)/types.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@"