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