os.ha (6061B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use fs; 5 use io; 6 use path; 7 use time; 8 9 // Provides an implementation of [[fs::fs]] for the current working directory. 10 export let cwd: *fs::fs = null: *fs::fs; 11 12 // Removes a file. 13 export fn remove(path: str) (void | fs::error) = fs::remove(cwd, path); 14 15 // Renames a file. This generally only works if the source and destination path 16 // are both on the same filesystem. See [[move]] for an implementation which 17 // falls back on a "copy & remove" procedure in this situation. 18 export fn rename(oldpath: str, newpath: str) (void | fs::error) = 19 fs::rename(cwd, oldpath, newpath); 20 21 // Moves a file. This will use [[rename]] if possible, and will fall back to 22 // copy and remove if necessary. 23 export fn move(oldpath: str, newpath: str) (void | fs::error) = 24 fs::move(cwd, oldpath, newpath); 25 26 // Creates an [[fs::iterator]] for a given directory to read its contents. The 27 // user should call [[fs::next]] to enumerate entries, and [[fs::finish]] when 28 // done using the object. 29 export fn iter(path: str) (*fs::iterator | fs::error) = fs::iter(cwd, path); 30 31 // Reads all entries from a directory. The caller must free the return value 32 // with [[fs::dirents_free]]. 33 export fn readdir(path: str) ([]fs::dirent | fs::error) = fs::readdir(cwd, path); 34 35 // Returns file information for a given path. If the target is a symlink, 36 // information is returned about the link, not its target. 37 export fn stat(path: str) (fs::filestat | fs::error) = fs::stat(cwd, path); 38 39 // Returns file information for an [[io::file]]. 40 export fn fstat(fd: io::file) (fs::filestat | fs::error) = fs::fstat(cwd, fd); 41 42 // Returns true if a node exists at the given path, or false if not. 43 // 44 // Note that testing for file existence before using the file can often lead to 45 // race conditions. If possible, prefer to simply attempt to use the file (e.g. 46 // via "open"), and handle the resulting error should the file not exist. 47 export fn exists(path: str) bool = fs::exists(cwd, path); 48 49 // Creates a directory. 50 export fn mkdir(path: str, mode: fs::mode) (void | fs::error) = fs::mkdir(cwd, path, mode); 51 52 // Creates a directory, and all non-extant directories in its path. 53 export fn mkdirs(path: str, mode: fs::mode) (void | fs::error) = fs::mkdirs(cwd, path, mode); 54 55 // Removes a directory. The target directory must be empty; see [[rmdirall]] to 56 // remove its contents as well. 57 export fn rmdir(path: str) (void | fs::error) = fs::rmdir(cwd, path); 58 59 // Removes a directory, and anything in it. 60 export fn rmdirall(path: str) (void | fs::error) = fs::rmdirall(cwd, path); 61 62 // Changes mode flags on a file or directory. Type bits are discared. 63 export fn chmod(path: str, mode: fs::mode) (void | fs::error) = fs::chmod(cwd, path, mode); 64 65 // Changes mode flags on a [[io::file]]. Type bits are discared. 66 export fn fchmod(fd: io::file, mode: fs::mode) (void | fs::error) = fs::fchmod(cwd, fd, mode); 67 68 // Changes ownership of a file. 69 export fn chown(path: str, uid: uint, gid: uint) (void | fs::error) = fs::chown(cwd, path, uid, gid); 70 71 // Changes ownership of a [io::file]]. 72 export fn fchown(fd: io::file, uid: uint, gid: uint) (void | fs::error) = fs::fchown(cwd, fd, uid, gid); 73 74 // Changes the access and modification time of a file. A void value will leave 75 // the corresponding time unchanged. 76 export fn chtimes( 77 path: str, 78 atime: (time::instant | void), 79 mtime: (time::instant | void) 80 ) (void | fs::error) = fs::chtimes(cwd, path, atime, mtime); 81 82 // Changes the access and modification time of an [[io::file]]. A void value 83 // will leave the corresponding time unchanged. 84 export fn fchtimes( 85 fd: io::file, 86 atime: (time::instant | void), 87 mtime: (time::instant | void) 88 ) (void | fs::error) = fs::fchtimes(cwd, fd, atime, mtime); 89 90 // Resolves a path to its absolute, normalized value. Relative paths will be 91 // rooted (if supported by the host filesystem), and "." and ".." components 92 // will be reduced. This function does not follow symlinks; see [[realpath]] if 93 // you need this behavior. The return value is statically allocated; use 94 // [[strings::dup]] to extend its lifetime. 95 export fn resolve(path: str) str = fs::resolve(cwd, path); 96 97 // Returns the path referred to by a symbolic link. The return value is 98 // statically allocated and will be overwritten on subsequent calls. 99 export fn readlink(path: str) (str | fs::error) = fs::readlink(cwd, path); 100 101 // Creates a new (hard) link at 'new' for the file at 'old'. 102 export fn link(old: str, new: str) (void | fs::error) = fs::link(cwd, old, new); 103 104 // Creates a new symbolic link at 'path' which points to 'target'. 105 export fn symlink(target: str, path: str) (void | fs::error) = 106 fs::symlink(cwd, target, path); 107 108 // Opens a file. 109 // 110 // [[fs::flag::CREATE]] isn't very useful with this function, since the new 111 // file's mode is set to zero. For this use-case, use [[create]] instead. 112 export fn open( 113 path: str, 114 flags: fs::flag = fs::flag::RDONLY, 115 ) (io::file | fs::error) = fs::open_file(cwd, path, flags); 116 117 // Creates a new file with the given mode if it doesn't already exist and opens 118 // it for writing. 119 // 120 // Only the permission bits of the mode are used. If other bits are set, they 121 // are discarded. 122 // 123 // To create a file without opening it, see [[mkfile]]. 124 export fn create( 125 path: str, 126 mode: fs::mode, 127 flags: fs::flag = fs::flag::WRONLY | fs::flag::TRUNC, 128 ) (io::file | fs::error) = fs::create_file(cwd, path, mode, flags); 129 130 // Canonicalizes a path in this filesystem by resolving all symlinks and 131 // collapsing any "." or ".." path components. 132 // 133 // This function is a thin shim over [[fs::realpath]], and the return value is 134 // statically allocated by [[fs::realpath]]. Thus, calls to this function or to 135 // [[fs::realpath]] will overwrite the return value of either function. 136 export fn realpath(path: str) (str | fs::error) = fs::realpath(cwd, path); 137 138 // Opens a directory as a filesystem. 139 export fn diropen(path: str) (*fs::fs | fs::error) = { 140 const file = open(path, fs::flag::DIRECTORY | fs::flag::RDONLY)?; 141 return dirfdopen(file); 142 };