hare

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

fs.ha (2376B)


      1 // License: MPL-2.0
      2 // (c) 2021 Drew DeVault <sir@cmpwn.com>
      3 // (c) 2021 Eyal Sawady <ecs@d2evs.net>
      4 use errors;
      5 use fs;
      6 use path;
      7 use rt;
      8 use strings;
      9 
     10 export fn init_cwd() void = {
     11 	// XXX: Workaround for https://todo.sr.ht/~sircmpwn/hare/616
     12 	static let cwd_fs = os_filesystem { ... };
     13 	if (cwd_fs.dirfd == 0) {
     14 		cwd = static_dirfdopen(rt::AT_FDCWD, &cwd_fs);
     15 	};
     16 };
     17 
     18 @init fn init() void = {
     19 	init_cwd();
     20 };
     21 
     22 // Returns the current working directory. The return value is statically
     23 // allocated and must be duplicated (see [[strings::dup]]) before calling getcwd
     24 // again.
     25 export fn getcwd() str = strings::fromc(rt::getcwd() as *const char);
     26 
     27 // Change the current working directory.
     28 export fn chdir(target: (*fs::fs | str)) (void | fs::error) = {
     29 	const path: str = match (target) {
     30 	case let fs: *fs::fs =>
     31 		assert(fs.open == &fs_open);
     32 		let fs = fs: *os_filesystem;
     33 		match (rt::fchdir(fs.dirfd)) {
     34 		case let err: rt::errno =>
     35 			return errors::errno(err);
     36 		case void =>
     37 			return;
     38 		};
     39 	case let s: str =>
     40 		yield s;
     41 	};
     42 	match (rt::chdir(path)) {
     43 	case let err: rt::errno =>
     44 		return errors::errno(err);
     45 	case void => void;
     46 	};
     47 };
     48 
     49 // Changes the root directory of the process. Generally requires the caller to
     50 // have root or otherwise elevated permissions.
     51 //
     52 // This function is not appropriate for sandboxing.
     53 export fn chroot(target: str) (void | fs::error) = {
     54 	match (rt::chroot(target)) {
     55 	case let err: rt::errno =>
     56 		return errors::errno(err);
     57 	case void => void;
     58 	};
     59 };
     60 
     61 // Access modes for [[access]].
     62 export type amode = enum int {
     63 	F_OK = rt::F_OK,
     64 	R_OK = rt::R_OK,
     65 	W_OK = rt::W_OK,
     66 	X_OK = rt::X_OK,
     67 };
     68 
     69 // Returns true if the given mode of access is permissible. The use of this
     70 // function is discouraged as it can allow for a race condition to occur betwen
     71 // testing for the desired access mode and actually using the file should the
     72 // permissions of the file change between these operations. It is recommended
     73 // instead to attempt to use the file directly and to handle any errors that
     74 // should occur at that time.
     75 export fn access(path: str, mode: amode) (bool | fs::error) = {
     76 	match (rt::access(path, mode)) {
     77 	case let b: bool =>
     78 		return b;
     79 	case let err: rt::errno =>
     80 		return errno_to_fs(err);
     81 	};
     82 };
     83 
     84 // TODO: FreeBSD
     85 // export fn mkfifo(path: str, mode: fs::mode) (void | fs::error) = {
     86 // export fn mkblk(
     87 // export fn mkchr(