hare

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

commit ceced1c9798955c1605b4bf008c78c49c795269c
parent d41935e960b36b6e741039e277c88afd2f143d25
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 24 Feb 2021 17:35:14 -0500

os: add os::chdir, os::chroot

Diffstat:
Mos/+linux/fs.ha | 36++++++++++++++++++++++++++++++++++++
Mrt/+linux/syscalls.ha | 5+++++
2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/os/+linux/fs.ha b/os/+linux/fs.ha @@ -1,5 +1,6 @@ use fs; use rt; +use strings; @init fn init() void = { static let root_fs = os_filesystem { ... }; @@ -10,3 +11,38 @@ use rt; static let cwd_fs = os_filesystem { ... }; cwd = static_dirfdopen(rt::AT_FDCWD, &cwd_fs); }; + +// Change the current working directory. +export fn chdir(target: (*fs::fs | ...fs::path)) (void | fs::error) = { + const path: []u8 = match (target) { + fs: *fs::fs => { + assert(fs.open == &fs_open); + let fs = fs: *os_filesystem; + return match (rt::fchdir(fs.dirfd)) { + err: rt::errno => errno_to_io(err): fs::error, + void => void, + }; + }, + s: str => strings::to_utf8(s), + b: []u8 => b, + }; + return match (rt::chdir(path: *[*]u8: *const char)) { + err: rt::errno => errno_to_io(err): fs::error, + void => void, + }; +}; + +// Changes the root directory of the process. Generally requires the caller to +// have root or otherwise elevated permissions. +// +// This function is not appropriate for sandboxing. +export fn chroot(target: fs::path) (void | fs::error) = { + const path: []u8 = match (target) { + s: str => strings::to_utf8(s), + b: []u8 => b, + }; + return match (rt::chroot(path: *[*]u8: *const char)) { + err: rt::errno => errno_to_io(err): fs::error, + void => void, + }; +}; diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -50,6 +50,11 @@ export fn fchdir(fd: int) (void | errno) = { return; }; +export fn chroot(path: *const char) (void | errno) = { + wrap_return(syscall1(SYS_chroot, path: uintptr: u64))?; + return; +}; + export fn execveat(dirfd: int, path: *const char, argv: *[*]nullable *const char, envp: *[*]nullable *const char, flags: int) errno = { return match (wrap_return(syscall5(SYS_execveat, dirfd: u64,