commit f977d0a8af5f3cd277f7280e78cc57a9f2af5856
parent 5aefaad5fca9fd8078d03e45c6338883f7623a4f
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 9 Mar 2021 15:36:57 -0500
os: dirfdfs: implement remove, rmdir
Diffstat:
2 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha
@@ -46,10 +46,12 @@ fn static_dirfdopen(fd: int, filesystem: *os_filesystem) *fs::fs = {
fs = fs::fs {
open = &fs_open,
create = &fs_create,
+ remove = &fs_remove,
iter = &fs_iter,
stat = &fs_stat,
subdir = &fs_subdir,
mkdir = &fs_mkdir,
+ rmdir = &fs_rmdir,
resolve = &fs_resolve,
...
},
@@ -188,6 +190,14 @@ fn fs_create(
return _fs_open(fs, path, iomode, &oh);
};
+fn fs_remove(fs: *fs::fs, path: path::path) (void | fs::error) = {
+ let fs = fs: *os_filesystem;
+ match (rt::unlinkat(fs.dirfd, path, 0)) {
+ err: rt::errno => return errno_to_io(err),
+ void => void,
+ };
+};
+
fn fs_stat(fs: *fs::fs, path: path::path) (fs::filestat | fs::error) = {
let fs = fs: *os_filesystem;
let st = rt::st { ... };
@@ -224,6 +234,14 @@ fn fs_subdir(fs: *fs::fs, path: path::path) (*fs::fs | fs::error) = {
return dirfdopen(fd);
};
+fn fs_rmdir(fs: *fs::fs, path: path::path) (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),
+ void => void,
+ };
+};
+
fn fs_mkdir(fs: *fs::fs, path: path::path) (void | fs::error) = {
let fs = fs: *os_filesystem;
return match (rt::mkdirat(fs.dirfd, path, 0o755)) {
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -60,6 +60,20 @@ export fn openat2(
path: uintptr: u64, how: uintptr: u64, how_sz: u64))?: int;
};
+export fn unlink(path: path) (void | errno) = {
+ let path = kpath(path)?;
+ wrap_return(syscall3(SYS_unlinkat,
+ AT_FDCWD: u64, path: uintptr: u64, 0u64));
+ return;
+};
+
+export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = {
+ let path = kpath(path)?;
+ wrap_return(syscall3(SYS_unlinkat,
+ dirfd: u64, path: uintptr: u64, flags: u64));
+ return;
+};
+
export fn dup(fd: int) (int | errno) = {
return wrap_return(syscall1(SYS_dup, fd: u64))?: int;
};