commit c0432c642c35ac59b88f2ab9ad7f8898dbd3799e
parent 546d15baeed597c3d73894af5845ceb5ee1d6812
Author: Curtis Arthaud <uku82@gmx.fr>
Date: Sun, 7 Apr 2024 09:57:43 +0200
os: add fchmod, fchown
Signed-off-by: Curtis Arthaud <uku82@gmx.fr>
Diffstat:
6 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/fs/fs.ha b/fs/fs.ha
@@ -264,6 +264,16 @@ export fn chmod(fs: *fs, path: str, mode: mode) (void | error) = {
};
};
+// Changes mode flags on a [[io::file]].
+export fn fchmod(fs: *fs, fd: io::file, mode: mode) (void | error) = {
+ match (fs.fchmod) {
+ case null =>
+ return errors::unsupported;
+ case let f: *fchmodfunc =>
+ return f(fd, mode);
+ };
+};
+
// Changes ownership of a file.
export fn chown(fs: *fs, path: str, uid: uint, gid: uint) (void | error) = {
match (fs.chown) {
@@ -274,6 +284,16 @@ export fn chown(fs: *fs, path: str, uid: uint, gid: uint) (void | error) = {
};
};
+// Changes ownership of a [[io::file]].
+export fn fchown(fs: *fs, fd: io::file, uid: uint, gid: uint) (void | error) = {
+ match (fs.fchown) {
+ case null =>
+ return errors::unsupported;
+ case let f: *fchownfunc =>
+ return f(fd, uid, gid);
+ };
+};
+
// Changes the access and modification time of a file. A void value will leave
// the corresponding time unchanged.
export fn chtimes(
diff --git a/fs/types.ha b/fs/types.ha
@@ -207,7 +207,9 @@ export type fstatfunc = fn(fs: *fs, file: io::file) (filestat | error);
export type mkdirfunc = fn(fs: *fs, path: str, mode: mode) (void | error);
export type rmdirfunc = fn(fs: *fs, path: str) (void | error);
export type chmodfunc = fn(fs: *fs, path: str, mode: mode) (void | error);
+export type fchmodfunc = fn(fd: io::file, mode: mode) (void | error);
export type chownfunc = fn(fs: *fs, path: str, uid: uint, gid: uint) (void | error);
+export type fchownfunc = fn(fd: io::file, uid: uint, gid: uint) (void | error);
export type chtimesfunc = fn(fs: *fs, path: str, atime: (time::instant | void),
mtime: (time::instant | void)) (void | error);
export type fchtimesfunc = fn(fd: io::file, atime: (time::instant | void),
@@ -300,9 +302,15 @@ export type fs = struct {
// Changes mode flags on a file or directory.
chmod: nullable *chmodfunc,
+ // Changes mode flags on a [[io::file]].
+ fchmod: nullable *fchmodfunc,
+
// Changes ownership of a file.
chown: nullable *chownfunc,
+ // Changes ownership of a [[io::file]].
+ fchown: nullable *fchownfunc,
+
// Changes access and modification time of a file.
chtimes: nullable *chtimesfunc,
diff --git a/os/+freebsd/dirfdfs.ha b/os/+freebsd/dirfdfs.ha
@@ -309,6 +309,14 @@ fn fs_chmod(fs: *fs::fs, path: str, mode: fs::mode) (void | fs::error) = {
};
};
+fn fs_fchmod(fd: io::file, mode: fs::mode) (void | fs::error) = {
+ match (rt::fchmod(fd, mode: uint)) {
+ case let err: rt::errno =>
+ return errno_to_fs(err);
+ case void => void;
+ };
+};
+
fn fs_chown(fs: *fs::fs, path: str, uid: uint, gid: uint) (void | fs::error) = {
let fs = fs: *os_filesystem;
match (rt::fchownat(fs.dirfd, path, uid, gid, 0)) {
@@ -318,6 +326,14 @@ fn fs_chown(fs: *fs::fs, path: str, uid: uint, gid: uint) (void | fs::error) = {
};
};
+fn fs_fchown(fd: io::file, uid: uint, gid: uint) (void | fs::error) = {
+ match (rt::fchown(fd, uid, gid)) {
+ case let err: rt::errno =>
+ return errno_to_fs(err);
+ case void => void;
+ };
+};
+
fn instant_to_timespec(time: (time::instant | void)) rt::timespec = {
match (time) {
case let t: time::instant =>
diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha
@@ -76,7 +76,9 @@ fn static_dirfdopen(fd: io::file, filesystem: *os_filesystem) *fs::fs = {
mkdir = &fs_mkdir,
rmdir = &fs_rmdir,
chmod = &fs_chmod,
+ fchmod = &fs_fchmod,
chown = &fs_chown,
+ fchown = &fs_fchown,
chtimes = &fs_chtimes,
fchtimes = &fs_fchtimes,
resolve = &fs_resolve,
@@ -338,6 +340,14 @@ fn fs_chmod(fs: *fs::fs, path: str, mode: fs::mode) (void | fs::error) = {
};
};
+fn fs_fchmod(fd: io::file, mode: fs::mode) (void | fs::error) = {
+ match (rt::fchmod(fd, mode: uint)) {
+ case let err: rt::errno =>
+ return errno_to_fs(err);
+ case void => void;
+ };
+};
+
fn fs_chown(fs: *fs::fs, path: str, uid: uint, gid: uint) (void | fs::error) = {
let fs = fs: *os_filesystem;
match (rt::fchownat(fs.dirfd, path, uid, gid, 0)) {
@@ -347,6 +357,14 @@ fn fs_chown(fs: *fs::fs, path: str, uid: uint, gid: uint) (void | fs::error) = {
};
};
+fn fs_fchown(fd: io::file, uid: uint, gid: uint) (void | fs::error) = {
+ match (rt::fchown(fd, uid, gid)) {
+ case let err: rt::errno =>
+ return errno_to_fs(err);
+ case void => void;
+ };
+};
+
fn instant_to_timespec(time: (time::instant | void)) rt::timespec = {
match (time) {
case let t: time::instant =>
diff --git a/os/+openbsd/dirfdfs.ha b/os/+openbsd/dirfdfs.ha
@@ -333,6 +333,14 @@ fn fs_chmod(fs: *fs::fs, path: str, mode: fs::mode) (void | fs::error) = {
};
};
+fn fs_fchmod(fd: io::file, mode: fs::mode) (void | fs::error) = {
+ match (rt::fchmod(fd, mode: uint)) {
+ case let err: rt::errno =>
+ return errno_to_fs(err);
+ case void => void;
+ };
+};
+
fn fs_chown(fs: *fs::fs, path: str, uid: uint, gid: uint) (void | fs::error) = {
let fs = fs: *os_filesystem;
match (rt::fchownat(fs.dirfd, path, uid, gid, 0)) {
@@ -342,6 +350,14 @@ fn fs_chown(fs: *fs::fs, path: str, uid: uint, gid: uint) (void | fs::error) = {
};
};
+fn fs_fchown(fd: io::file, uid: uint, gid: uint) (void | fs::error) = {
+ match (rt::fchown(fd, uid, gid)) {
+ case let err: rt::errno =>
+ return errno_to_fs(err);
+ case void => void;
+ };
+};
+
fn instant_to_timespec(time: (time::instant | void)) rt::timespec = {
match (time) {
case let t: time::instant =>
diff --git a/os/os.ha b/os/os.ha
@@ -62,9 +62,15 @@ export fn rmdirall(path: str) (void | fs::error) = fs::rmdirall(cwd, path);
// Changes mode flags on a file or directory. Type bits are discared.
export fn chmod(path: str, mode: fs::mode) (void | fs::error) = fs::chmod(cwd, path, mode);
+// Changes mode flags on a [[io::file]]. Type bits are discared.
+export fn fchmod(fd: io::file, mode: fs::mode) (void | fs::error) = fs::fchmod(cwd, fd, mode);
+
// Changes ownership of a file.
export fn chown(path: str, uid: uint, gid: uint) (void | fs::error) = fs::chown(cwd, path, uid, gid);
+// Changes ownership of a [io::file]].
+export fn fchown(fd: io::file, uid: uint, gid: uint) (void | fs::error) = fs::fchown(cwd, fd, uid, gid);
+
// Changes the access and modification time of a file. A void value will leave
// the corresponding time unchanged.
export fn chtimes(