hare

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

commit 145dc1da06092efe55c70104c6441d7ff324255e
parent d1dc25addcf28f91817c425b1ee67a3b015d1216
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 14 Mar 2021 10:23:17 -0400

fs: add busy error; expand dirfd support

Diffstat:
Mfs/types.ha | 10+++++++++-
Mos/+linux/dirfdfs.ha | 32+++++++++++++++++---------------
2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/fs/types.ha b/fs/types.ha @@ -11,12 +11,20 @@ export type exists = void!; // The user does not have permission to use this resource. export type noaccess = void!; +// The requested file is not available. +export type busy = void!; + // An entry of a particular type was sought, but is something else in practice. // For example, opening a file with [iter]. export type wrongtype = void!; // All possible fs error types. -export type error = (noentry | noaccess | exists | wrongtype | io::error)!; +export type error = (noentry + | noaccess + | exists + | busy + | wrongtype + | io::error)!; // File mode information. These bits do not necessarily reflect the underlying // operating system's mode representation, though they were chosen to be diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha @@ -90,6 +90,16 @@ export fn dirfs_clone(fs: *fs::fs, resolve: resolve_flags...) *fs::fs = { return &new.fs; }; +fn errno_to_fs(err: rt::errno) fs::error = switch (err) { + rt::ENOENT => fs::noentry, + rt::EEXIST => fs::exists, + rt::EACCES => fs::noaccess, + rt::EBUSY => fs::busy, + rt::ENOTDIR => fs::wrongtype, + rt::EOPNOTSUPP, rt::ENOSYS => io::unsupported, + * => errno_to_io(err), +}; + fn _fs_open( fs: *fs::fs, path: str, @@ -113,7 +123,7 @@ fn _fs_open( }; let fd = match (rt::openat2(fs.dirfd, path, oh, size(rt::open_how))) { - err: rt::errno => return errno_to_io(err), + err: rt::errno => return errno_to_fs(err), fd: int => fd, }; @@ -188,7 +198,7 @@ fn fs_create( fn fs_remove(fs: *fs::fs, path: str) (void | fs::error) = { let fs = fs: *os_filesystem; match (rt::unlinkat(fs.dirfd, path, 0)) { - err: rt::errno => return errno_to_io(err), + err: rt::errno => return errno_to_fs(err), void => void, }; }; @@ -197,7 +207,7 @@ fn fs_stat(fs: *fs::fs, path: str) (fs::filestat | fs::error) = { let fs = fs: *os_filesystem; let st = rt::st { ... }; match (rt::fstatat(fs.dirfd, path, &st, rt::AT_SYMLINK_NOFOLLOW)) { - err: rt::errno => return errno_to_io(err), + err: rt::errno => return errno_to_fs(err), void => void, }; return fs::filestat { @@ -222,7 +232,7 @@ fn fs_subdir(fs: *fs::fs, path: str) (*fs::fs | fs::error) = { let fd: int = match (rt::openat2(fs.dirfd, path, &oh, size(rt::open_how))) { - err: rt::errno => return errno_to_io(err), + err: rt::errno => return errno_to_fs(err), n: int => n, }; @@ -232,7 +242,7 @@ fn fs_subdir(fs: *fs::fs, path: str) (*fs::fs | fs::error) = { fn fs_rmdir(fs: *fs::fs, path: str) (void | fs::error) = { let fs = fs: *os_filesystem; match (rt::unlinkat(fs.dirfd, path, rt::AT_REMOVEDIR)) { - err: rt::errno => return errno_to_io(err), + err: rt::errno => return errno_to_fs(err), void => void, }; }; @@ -240,10 +250,7 @@ fn fs_rmdir(fs: *fs::fs, path: str) (void | fs::error) = { fn fs_mkdir(fs: *fs::fs, path: str) (void | fs::error) = { let fs = fs: *os_filesystem; return match (rt::mkdirat(fs.dirfd, path, 0o755)) { - err: rt::errno => switch (err) { - rt::EEXIST => fs::exists, - * => errno_to_io(err), - }, + err: rt::errno => errno_to_fs(err), void => void, }; }; @@ -303,12 +310,7 @@ fn fs_iter(fs: *fs::fs, path: str) (*fs::iterator | fs::error) = { }; let fd: int = match (rt::openat2(fs.dirfd, path, &oh, size(rt::open_how))) { - err: rt::errno => { - if (err: int == rt::ENOTDIR) { - return fs::wrongtype; - }; - return errno_to_io(err); - }, + err: rt::errno => return errno_to_fs(err), n: int => n, };