hare

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

os.ha (5318B)


      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 
      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 ownership of a file.
     65 export fn chown(path: str, uid: uint, gid: uint) (void | fs::error) = fs::chown(cwd, path, uid, gid);
     66 
     67 // Resolves a path to its absolute, normalized value. Relative paths will be
     68 // rooted (if supported by the host filesystem), and "." and ".." components
     69 // will be reduced. This function does not follow symlinks; see [[realpath]] if
     70 // you need this behavior. The return value is statically allocated; use
     71 // [[strings::dup]] to extend its lifetime.
     72 export fn resolve(path: str) str = fs::resolve(cwd, path);
     73 
     74 // Returns the path referred to by a symbolic link. The return value is
     75 // statically allocated and will be overwritten on subsequent calls.
     76 export fn readlink(path: str) (str | fs::error) = fs::readlink(cwd, path);
     77 
     78 // Creates a new (hard) link at 'new' for the file at 'old'.
     79 export fn link(old: str, new: str) (void | fs::error) = fs::link(cwd, old, new);
     80 
     81 // Creates a new symbolic link at 'path' which points to 'target'.
     82 export fn symlink(target: str, path: str) (void | fs::error) =
     83 	fs::symlink(cwd, target, path);
     84 
     85 // Opens a file.
     86 //
     87 // If no flags are provided, [[fs::flag::RDONLY]] is used when opening the
     88 // file.
     89 //
     90 // [[fs::flag::CREATE]] isn't very useful with this function, since the new
     91 // file's mode is set to zero. For this use-case, use [[create]] instead.
     92 export fn open(path: str, flags: fs::flag...) (io::file | fs::error) =
     93 	fs::open_file(cwd, path, flags...);
     94 
     95 // Creates a new file with the given mode if it doesn't already exist and opens
     96 // it for writing.
     97 //
     98 // If no flags are provided, [[fs::flag::WRONLY]] and [[fs::flag::TRUNC]] are
     99 // used when opening the file.
    100 //
    101 // Only the permission bits of the mode are used. If other bits are set, they
    102 // are discarded.
    103 //
    104 // To create a file without opening it, see [[mkfile]].
    105 export fn create(
    106 	path: str,
    107 	mode: fs::mode,
    108 	flags: fs::flag...
    109 ) (io::file | fs::error) = fs::create_file(cwd, path, mode, flags...);
    110 
    111 // Canonicalizes a path in this filesystem by resolving all symlinks and
    112 // collapsing any "." or ".." path components.
    113 //
    114 // This function is a thin shim over [[fs::realpath]], and the return value is
    115 // statically allocated by [[fs::realpath]]. Thus, calls to this function or to
    116 // [[fs::realpath]] will overwrite the return value of either function.
    117 export fn realpath(path: str) (str | fs::error) = fs::realpath(cwd, path);
    118 
    119 // Opens a directory as a filesystem.
    120 export fn diropen(path: str) (*fs::fs | fs::error) = {
    121 	const file = open(path, fs::flag::DIRECTORY | fs::flag::RDONLY)?;
    122 	return dirfdopen(file);
    123 };