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