fs.ha (2879B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use fs; 5 use io; 6 use rt; 7 use types::c; 8 9 @init fn init_cwd() void = { 10 static let cwd_fs = os_filesystem { ... }; 11 cwd = static_dirfdopen(rt::AT_FDCWD, &cwd_fs); 12 }; 13 14 // Returns the current working directory. The return value is statically 15 // allocated and must be duplicated (see [[strings::dup]]) before calling getcwd 16 // again. 17 export fn getcwd() str = c::tostr(rt::getcwd() as *const u8: *const c::char)!; 18 19 // Change the current working directory. 20 export fn chdir(target: (*fs::fs | str)) (void | fs::error) = { 21 const path: str = match (target) { 22 case let fs: *fs::fs => 23 assert(fs.open == &fs_open); 24 let fs = fs: *os_filesystem; 25 match (rt::fchdir(fs.dirfd)) { 26 case let err: rt::errno => 27 return errno_to_fs(err); 28 case void => 29 return; 30 }; 31 case let s: str => 32 yield s; 33 }; 34 match (rt::chdir(path)) { 35 case let err: rt::errno => 36 return errno_to_fs(err); 37 case void => void; 38 }; 39 }; 40 41 // Changes the root directory of the process. Generally requires the caller to 42 // have root or otherwise elevated permissions. 43 // 44 // This function is not appropriate for sandboxing. 45 export fn chroot(target: str) (void | fs::error) = { 46 match (rt::chroot(target)) { 47 case let err: rt::errno => 48 return errno_to_fs(err); 49 case void => void; 50 }; 51 }; 52 53 // Access modes for [[access]]. 54 export type amode = enum int { 55 F_OK = rt::F_OK, 56 R_OK = rt::R_OK, 57 W_OK = rt::W_OK, 58 X_OK = rt::X_OK, 59 }; 60 61 // Returns true if the given mode of access is permissible. The use of this 62 // function is discouraged as it can allow for a race condition to occur betwen 63 // testing for the desired access mode and actually using the file should the 64 // permissions of the file change between these operations. It is recommended 65 // instead to attempt to use the file directly and to handle any errors that 66 // should occur at that time. 67 export fn access(path: str, mode: amode) (bool | fs::error) = { 68 match (rt::access(path, mode)) { 69 case let b: bool => 70 return b; 71 case let err: rt::errno => 72 return errno_to_fs(err); 73 }; 74 }; 75 76 // Makes a FIFO node. This function is only available on Unix-like systems. 77 export fn mkfifo(path: str, mode: fs::mode) (void | fs::error) = { 78 match (rt::mknodat(rt::AT_FDCWD, path, 79 mode: rt::mode_t | rt::S_IFIFO, 0)) { 80 case let err: rt::errno => 81 return errno_to_fs(err); 82 case void => void; 83 }; 84 }; 85 86 // Makes a regular file. This function is only available on Unix-like systems. 87 // This function should only be used if you have a special reason; most of the 88 // time you should use [[create]] instead. 89 export fn mkfile(path: str, mode: fs::mode) (void | fs::error) = { 90 let file = match(rt::openat(rt::AT_FDCWD, path, rt::O_RDONLY | rt::O_CREAT, 91 mode: rt::mode_t)) { 92 case let f: int => 93 yield f: io::file; 94 case let err: rt::errno => 95 return errno_to_fs(err); 96 }; 97 io::close(file)?; 98 };