hare

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

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 };