hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

os.ha (6030B)


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