hare

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

shm.ha (2320B)


      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 strings;
     10 
     11 fn shm_path(name: str) (str | fs::error) = {
     12 	const name = strings::ltrim(name, '/');
     13 	if (len(name) > rt::NAME_MAX) {
     14 		return errors::invalid;
     15 	};
     16 	if (name == "." || name == "..") {
     17 		return errors::invalid;
     18 	};
     19 	static let buf = path::buffer { ... };
     20 	path::set(&buf, "/", name)!;
     21 	return path::string(&buf);
     22 };
     23 
     24 // Opens (or creates, given [[fs::flag::CREATE]]) a global shared memory file
     25 // with the given name, suitable for use with [[io::mmap]] to establish shared
     26 // memory areas with other processes using the same name.
     27 //
     28 // The name must not contain any forward slashes (one is permissible at the
     29 // start, e.g. "/example") and cannot be "." or "..".
     30 //
     31 // The "oflag" parameter, if provided, must include either [[fs::flag::RDONLY]]
     32 // or [[fs::flag::RDWR]], and may optionally add [[fs::flag::CREATE]],
     33 // [[fs::flag::EXCL]], and/or [[fs::flag::TRUNC]], other flags are silently
     34 // ignored if set.
     35 //
     36 // The new file descriptor always has CLOEXEC set regardless of the provided
     37 // flags. If creating a new shared memory object, set its initial size with
     38 // [[io::trunc]] before mapping it with [[io::mmap]].
     39 //
     40 // Call [[shm_unlink]] to remove the global shared memory object.
     41 export fn shm_open(
     42 	name: str,
     43 	oflag: fs::flag = fs::flag::CREATE | fs::flag::RDWR,
     44 	mode: fs::mode = 0o600,
     45 ) (io::file | fs::error) = {
     46 	const path = shm_path(name)?;
     47 	def VALID_FLAGS: int = rt::O_RDWR | rt::O_CREAT | rt::O_EXCL | rt::O_TRUNC;
     48 	const oflag = (fsflags_to_bsd(oflag)? & VALID_FLAGS) | rt::O_CLOEXEC;
     49 
     50 	match (rt::shm_open(path, oflag, mode: rt::mode_t)) {
     51 	case let fd: int =>
     52 		return fd: io::file;
     53 	case let err: rt::errno =>
     54 		return errors::errno(err): fs::error;
     55 	};
     56 };
     57 
     58 // Removes the shared memory object with the given name. Processes which already
     59 // hold a reference to the file may continue to use the memory associated with
     60 // it. Once all processes have unmapped the associated shared memory object, or
     61 // exited, the memory is released.
     62 export fn shm_unlink(name: str) (void | fs::error) = {
     63 	const path = shm_path(name)?;
     64 	match (rt::shm_unlink(path)) {
     65 	case let err: rt::errno =>
     66 		return errors::errno(err): fs::error;
     67 	case void =>
     68 		return;
     69 	};
     70 };