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:
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,