commit 41554c8429bd34efdd885c163bff8590205df604
parent 6b4df056c8f8ef475b00f4cbfb33ab17e329b639
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 7 May 2021 10:54:50 -0400
os: add mkfifo, mkblk, and mkchr functions
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
4 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/os/+linux/fs.ha b/os/+linux/fs.ha
@@ -43,3 +43,42 @@ export fn chroot(target: str) (void | fs::error) = {
void => void,
};
};
+
+// Makes a FIFO node. This function is only available on Unix systems.
+export fn mkfifo(path: str, mode: fs::mode) (void | fs::error) = {
+ return match (rt::mknodat(rt::AT_FDCWD, path,
+ mode: rt::mode_t | rt::S_IFIFO, 0)) {
+ err: rt::errno => errors::errno(err),
+ void => void,
+ };
+};
+
+// Makes a block device node. This function is only available on Unix systems.
+export fn mkblk(
+ path: str,
+ mode: fs::mode,
+ major: uint,
+ minor: uint,
+) (void | fs::error) = {
+ return match (rt::mknodat(rt::AT_FDCWD, path,
+ mode: rt::mode_t | rt::S_IFBLK,
+ rt::mkdev(major: u32, minor: u32))) {
+ err: rt::errno => errors::errno(err),
+ void => void,
+ };
+};
+
+// Makes a character device node. This function is only available on Unix systems.
+export fn mkchr(
+ path: str,
+ mode: fs::mode,
+ major: uint,
+ minor: uint,
+) (void | fs::error) = {
+ return match (rt::mknodat(rt::AT_FDCWD, path,
+ mode: rt::mode_t | rt::S_IFCHR,
+ rt::mkdev(major: u32, minor: u32))) {
+ err: rt::errno => errors::errno(err),
+ void => void,
+ };
+};
diff --git a/rt/+linux/stat.ha b/rt/+linux/stat.ha
@@ -1,4 +1,4 @@
-fn mkdev(major: u32, minor: u32) dev_t =
+export fn mkdev(major: u32, minor: u32) dev_t =
((major: u64 & 0xFFFFF000) << 32) |
((major: u64 & 0x00000FFF) << 8) |
((minor: u64 & 0xFFFFFF00) << 12) |
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -81,6 +81,18 @@ export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = {
return;
};
+export fn mknodat(
+ dirfd: int,
+ path: path,
+ mode: mode_t,
+ dev: dev_t,
+) (void | errno) = {
+ let path = kpath(path)?;
+ wrap_return(syscall3(SYS_mknodat,
+ path: uintptr: u64, mode: u64, dev: u64))?;
+ return;
+};
+
export fn chmod(path: path, mode: uint) (void | errno) = {
let path = kpath(path)?;
wrap_return(syscall3(SYS_fchmodat,
diff --git a/rt/+linux/types.ha b/rt/+linux/types.ha
@@ -48,6 +48,14 @@ export def AT_STATX_FORCE_SYNC: int = 0x2000;
export def AT_STATX_DONT_SYNC: int = 0x4000;
export def AT_RECURSIVE: int = 0x8000;
+export def S_IFDIR: mode_t = 0o040000;
+export def S_IFCHR: mode_t = 0o020000;
+export def S_IFBLK: mode_t = 0o060000;
+export def S_IFREG: mode_t = 0o100000;
+export def S_IFIFO: mode_t = 0o010000;
+export def S_IFLNK: mode_t = 0o120000;
+export def S_IFSOCK: mode_t = 0o140000;
+
// O_DIRECTORY is arch specific
export def O_RDONLY: int = 0o0;
export def O_WRONLY: int = 0o1;