hare

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

commit 03dfff2f8ead1006cf5c81cdff7ebfd820efc0ea
parent 5af7c7492be23d17f8b25a3669f15d380b383f76
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 11 Mar 2021 12:07:54 -0500

os: add os::resolve

Diffstat:
Mos/+linux/dirfdfs.ha | 18+++++++++---------
Mos/fs.ha | 5+++++
2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha @@ -12,7 +12,7 @@ use strings; // // Note that on Linux, specifying BENEATH or IN_ROOT will also disable magic // symlinks. -export type resolve = enum { +export type resolve_flags = enum { NORMAL, // Does not allow symlink resolution to occur for any symlinks which @@ -38,7 +38,7 @@ export type resolve = enum { type os_filesystem = struct { fs: fs::fs, dirfd: int, - resolve: resolve, + resolve: resolve_flags, }; fn static_dirfdopen(fd: int, filesystem: *os_filesystem) *fs::fs = { @@ -67,7 +67,7 @@ fn static_dirfdopen(fd: int, filesystem: *os_filesystem) *fs::fs = { // a dirfdfs, [fs::flags::NOCTTY] and [fs::flags::CLOEXEC] are used when opening // the file. If you pass your own flags, it is recommended that you add these // unless you know that you do not want them. -export fn dirfdopen(fd: int, resolve: resolve...) *fs::fs = { +export fn dirfdopen(fd: int, resolve: resolve_flags...) *fs::fs = { let ofs = alloc(os_filesystem { ... }); let fs = static_dirfdopen(fd, ofs); for (let i = 0z; i < len(resolve); i += 1) { @@ -77,9 +77,9 @@ export fn dirfdopen(fd: int, resolve: resolve...) *fs::fs = { return fs; }; -// Clones a dirfd filesystem, optionally adding additional [resolve] +// Clones a dirfd filesystem, optionally adding additional [resolve_flags] // constraints. -export fn dirfs_clone(fs: *fs::fs, resolve: resolve...) *fs::fs = { +export fn dirfs_clone(fs: *fs::fs, resolve: resolve_flags...) *fs::fs = { assert(fs.open == &fs_open); let fs = fs: *os_filesystem; let new = alloc(*fs); @@ -99,16 +99,16 @@ fn _fs_open( let fs = fs: *os_filesystem; oh.resolve = 0u64; - if (fs.resolve & resolve::BENEATH == resolve::BENEATH) { + if (fs.resolve & resolve_flags::BENEATH == resolve_flags::BENEATH) { oh.resolve |= rt::RESOLVE_BENEATH | rt::RESOLVE_NO_MAGICLINKS; }; - if (fs.resolve & resolve::IN_ROOT == resolve::IN_ROOT) { + if (fs.resolve & resolve_flags::IN_ROOT == resolve_flags::IN_ROOT) { oh.resolve |= rt::RESOLVE_IN_ROOT | rt::RESOLVE_NO_MAGICLINKS; }; - if (fs.resolve & resolve::NO_SYMLINKS == resolve::NO_SYMLINKS) { + if (fs.resolve & resolve_flags::NO_SYMLINKS == resolve_flags::NO_SYMLINKS) { oh.resolve |= rt::RESOLVE_NO_SYMLINKS; }; - if (fs.resolve & resolve::NO_XDEV == resolve::NO_XDEV) { + if (fs.resolve & resolve_flags::NO_XDEV == resolve_flags::NO_XDEV) { oh.resolve |= rt::RESOLVE_NO_XDEV; }; diff --git a/os/fs.ha b/os/fs.ha @@ -39,3 +39,8 @@ export fn rmdirall(path: str) (void | fs::error) = fs::rmdirall(cwd, path); // Creates a directory and returns a subdir for it. Some filesystems support // doing this operation atomically, but if not, a fallback is used. export fn mksubdir(path: str) (*fs::fs | fs::error) = fs::mksubdir(cwd, path); + +// Resolves a path to its absolute, normalized value. This consoldates ./ and +// ../ sequences, roots the path, and returns a new path. The caller must free +// the return value. +export fn resolve(path: str) str = fs::resolve(cwd, path);