hare

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

commit bbe5632fb90e548f8b312a049c5bae6701c553b9
parent 0794f2d0ac9547f111cf61f46581c4677c89fb8b
Author: Mallory Adams <malloryadams@fastmail.com>
Date:   Sun,  9 Jun 2024 20:18:14 -0400

NetBSD: add os::shm_open()

- Update rt/+netbsd/syscallno.ha with NetBSD 10.0 syscalls
- Add fstatvfs1 syscall
- Add unlink syscall
- Fix whitespace and comments in rt/+netbsd/types.ha

Signed-off-by: Mallory Adams <malloryadams@fastmail.com>

Diffstat:
Mmakefiles/netbsd.aarch64.mk | 4++--
Mmakefiles/netbsd.riscv64.mk | 4++--
Mmakefiles/netbsd.x86_64.mk | 4++--
Aos/+netbsd/shm.ha | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrt/+netbsd/syscallno.ha | 36++++++++++++++++++++++++++++++------
Mrt/+netbsd/syscalls.ha | 10++++++++++
Mrt/+netbsd/types.ha | 217++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
7 files changed, 369 insertions(+), 41 deletions(-)

diff --git a/makefiles/netbsd.aarch64.mk b/makefiles/netbsd.aarch64.mk @@ -129,8 +129,8 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha -$(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td +os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha +$(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/os.td.tmp -N os $(os_ha) diff --git a/makefiles/netbsd.riscv64.mk b/makefiles/netbsd.riscv64.mk @@ -129,8 +129,8 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha -$(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td +os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha +$(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/os.td.tmp -N os $(os_ha) diff --git a/makefiles/netbsd.x86_64.mk b/makefiles/netbsd.x86_64.mk @@ -129,8 +129,8 @@ $(HARECACHE)/types_c.ssa: $(types_c_ha) $(HARECACHE)/encoding_utf8.td $(HARECACH @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/types_c.td.tmp -N types::c $(types_c_ha) -os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha -$(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td +os_ha = os/+netbsd/dirfdfs.ha os/+netbsd/exit.ha os/+netbsd/fs.ha os/+netbsd/platform_environ.ha os/+netbsd/shm.ha os/+netbsd/status.ha os/+netbsd/stdfd.ha os/environ.ha os/os.ha +$(HARECACHE)/os.ssa: $(os_ha) $(HARECACHE)/bufio.td $(HARECACHE)/bytes.td $(HARECACHE)/errors.td $(HARECACHE)/fs.td $(HARECACHE)/io.td $(HARECACHE)/path.td $(HARECACHE)/rt.td $(HARECACHE)/strings.td $(HARECACHE)/time.td $(HARECACHE)/types_c.td @mkdir -p -- "$(HARECACHE)" @printf 'HAREC\t%s\n' "$@" @$(TDENV) $(HAREC) $(HARECFLAGS) -o $@ -t $(HARECACHE)/os.td.tmp -N os $(os_ha) diff --git a/os/+netbsd/shm.ha b/os/+netbsd/shm.ha @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +use bytes; +use errors; +use fs; +use io; +use path; +use rt; +use strings; + +fn shm_check_fs() bool = { + match (open(rt::SHMFS_DIR_PATH, + fs::flag::DIRECTORY | fs::flag::RDONLY)) { + case fs::error => + return false; + case let fd: io::file => + defer io::close(fd)!; + + let sv = rt::statvfs{...}; + let st = rt::st{...}; + + if (rt::fstatvfs1(fd, &sv, rt::MNT_NOWAIT) is rt::errno) + return false; + + if (strings::fromutf8(sv.f_fstypename)! == rt::MOUNT_SHMFS) + return false; + + if (rt::fstat(fd, &st) is rt::errno) + return false; + + if ((st.mode & rt::SHMFS_DIR_MODE) != rt::SHMFS_DIR_MODE) + return false; + + return true; + }; +}; + +fn shm_get_path(name: const str) (str | fs::error) = { + if (!shm_check_fs()) + return errors::errno(rt::ENOTSUP): fs::error; + + // The name may start with a slash character. + if (strings::hasprefix(name, '/')) { + name = strings::sub(name, 1); + }; + + // We may disallow other slashes (implementation-defined behaviour). + if (strings::contains(name, '/')) + return errors::errno(rt::EINVAL): fs::error; + + const _path = strings::concat( + rt::SHMFS_DIR_PATH, "/", rt::SHMFS_OBJ_PREFIX, name); + + if (len(_path) > path::MAX) + return errors::errno(rt::ENAMETOOLONG): fs::error; + + return _path; +}; + +// Opens (or creates, given [[fs::flag::CREATE]]) a global shared memory file +// with the given name, suitable for use with [[io::mmap]] to establish shared +// memory areas with other processes using the same name. +// +// The name must not contain any forward slashes (one is permissible at the +// start, e.g. "/example") and cannot be "." or "..". +// +// The "oflag" parameter, if provided, must include either [[fs::flag::RDONLY]] +// or [[fs::flag::RDWR]], and may optionally add [[fs::flag::CREATE]], +// [[fs::flag::EXCL]], and/or [[fs::flag::TRUNC]], which are supported on all +// POSIX-compatible platforms. Other platforms may support additional +// non-standard flags; consult the shm_open(3) manual for your target system for +// details. +// +// The new file descriptor always has CLOEXEC set regardless of the provided +// flags. If creating a new shared memory object, set its initial size with +// [[io::trunc]] before mapping it with [[io::mmap]]. +// +// Call [[shm_unlink]] to remove the global shared memory object. +export fn shm_open( + name: str, + oflag: fs::flag = fs::flag::CREATE | fs::flag::RDWR, + mode: fs::mode = 0o600, +) (io::file | fs::error) = { + const _path = shm_get_path(name)?; + + const oflag = fsflags_to_bsd(oflag)? | rt::O_CLOEXEC | rt::O_NOFOLLOW; + + match (rt::open(_path, oflag, mode)) { + case let fd: int => + return fd: io::file; + case let err: rt::errno => + return errors::errno(err): fs::error; + }; +}; + +// Removes the shared memory object with the given name. Processes which already +// hold a reference to the file may continue to use the memory associated with +// it. Once all processes have unmapped the associated shared memory object, or +// exited, the memory is released. +export fn shm_unlink(name: str) (void | fs::error) = { + const _path = shm_get_path(name)?; + + match (rt::unlink(_path)) { + case void => + void; + case let err: rt::errno => + return errors::errno(err): fs::error; + }; +}; + +@test fn shm_open() void = { + const name = "/vizzini"; + const value = "inconceivable"; + def length = 13; + + const fd = shm_open(name)!; + defer shm_unlink(name)!; + io::trunc(fd, length)!; + io::write(fd, strings::toutf8(value))!; + + { + const fd = shm_open(name, fs::flag::RDONLY, 0o600)!; + + let b: [length]u8 = [0...]; + io::read(fd, b)!; + assert(strings::fromutf8(b)! == value); + }; +}; + +@test fn shm_get_path() void = { + assert(shm_get_path("/ab/c") is fs::error); + assert(shm_get_path("abc"): str == "/var/shm/.shmobj_abc"); + assert(shm_get_path("/abc"): str == "/var/shm/.shmobj_abc"); +}; diff --git a/rt/+netbsd/syscallno.ha b/rt/+netbsd/syscallno.ha @@ -116,6 +116,8 @@ export def SYS_compat_50_settimeofday: u64 = 122; export def SYS_fchown: u64 = 123; export def SYS_fchmod: u64 = 124; export def SYS_compat_43_orecvfrom: u64 = 125; +export def SYS_setreuid: u64 = 126; +export def SYS_setregid: u64 = 127; export def SYS_rename: u64 = 128; export def SYS_compat_43_otruncate: u64 = 129; export def SYS_compat_43_oftruncate: u64 = 130; @@ -147,6 +149,9 @@ export def SYS_compat_09_ogetdomainname: u64 = 162; export def SYS_compat_09_osetdomainname: u64 = 163; export def SYS_compat_09_ouname: u64 = 164; export def SYS_sysarch: u64 = 165; +export def SYS___futex: u64 = 166; +export def SYS___futex_set_robust_list: u64 = 167; +export def SYS___futex_get_robust_list: u64 = 168; export def SYS_compat_10_osemsys: u64 = 169; export def SYS_compat_10_omsgsys: u64 = 170; export def SYS_compat_10_oshmsys: u64 = 171; @@ -154,6 +159,9 @@ export def SYS_pread: u64 = 173; export def SYS_pwrite: u64 = 174; export def SYS_compat_30_ntp_gettime: u64 = 175; export def SYS_ntp_adjtime: u64 = 176; +export def SYS_timerfd_create: u64 = 177; +export def SYS_timerfd_settime: u64 = 178; +export def SYS_timerfd_gettime: u64 = 179; export def SYS_setgid: u64 = 181; export def SYS_setegid: u64 = 182; export def SYS_seteuid: u64 = 183; @@ -231,6 +239,7 @@ export def SYS_mq_send: u64 = 263; export def SYS_mq_receive: u64 = 264; export def SYS_compat_50_mq_timedsend: u64 = 265; export def SYS_compat_50_mq_timedreceive: u64 = 266; +export def SYS_eventfd: u64 = 267; export def SYS___posix_rename: u64 = 270; export def SYS_swapctl: u64 = 271; export def SYS_compat_30_getdents: u64 = 272; @@ -305,9 +314,9 @@ export def SYS_sched_yield: u64 = 350; export def SYS__sched_protect: u64 = 351; export def SYS_fsync_range: u64 = 354; export def SYS_uuidgen: u64 = 355; -export def SYS_getvfsstat: u64 = 356; -export def SYS_statvfs1: u64 = 357; -export def SYS_fstatvfs1: u64 = 358; +export def SYS_compat_90_getvfsstat: u64 = 356; +export def SYS_compat_90_statvfs1: u64 = 357; +export def SYS_compat_90_fstatvfs1: u64 = 358; export def SYS_compat_30_fhstatvfs1: u64 = 359; export def SYS_extattrctl: u64 = 360; export def SYS_extattr_set_file: u64 = 361; @@ -345,7 +354,7 @@ export def SYS_compat_50___ntp_gettime30: u64 = 393; export def SYS___socket30: u64 = 394; export def SYS___getfh30: u64 = 395; export def SYS___fhopen40: u64 = 396; -export def SYS___fhstatvfs140: u64 = 397; +export def SYS_compat_90_fhstatvfs1: u64 = 397; export def SYS_compat_50___fhstat40: u64 = 398; export def SYS_aio_cancel: u64 = 399; export def SYS_aio_error: u64 = 400; @@ -427,5 +436,20 @@ export def SYS_posix_fallocate: u64 = 479; export def SYS_fdiscard: u64 = 480; export def SYS_wait6: u64 = 481; export def SYS_clock_getcpuclockid2: u64 = 482; -export def SYS_MAXSYSCALL: u64 = 483; -export def SYS_NSYSENT: u64 = 512; +export def SYS___getvfsstat90: u64 = 483; +export def SYS___statvfs190: u64 = 484; +export def SYS___fstatvfs190: u64 = 485; +export def SYS___fhstatvfs190: u64 = 486; +export def SYS___acl_get_link: u64 = 487; +export def SYS___acl_set_link: u64 = 488; +export def SYS___acl_delete_link: u64 = 489; +export def SYS___acl_aclcheck_link: u64 = 490; +export def SYS___acl_get_file: u64 = 491; +export def SYS___acl_set_file: u64 = 492; +export def SYS___acl_get_fd: u64 = 493; +export def SYS___acl_set_fd: u64 = 494; +export def SYS___acl_delete_file: u64 = 495; +export def SYS___acl_delete_fd: u64 = 496; +export def SYS___acl_aclcheck_file: u64 = 497; +export def SYS___acl_aclcheck_fd: u64 = 498; +export def SYS_lpathconf: u64 = 499; diff --git a/rt/+netbsd/syscalls.ha b/rt/+netbsd/syscalls.ha @@ -79,6 +79,11 @@ export fn fstatat(fd: int, path: path, _stat: *st, flag: int) (void | errno) = { _stat.flags = sb.st_flags; }; +export fn fstatvfs1(fd: int, _statvfs: *statvfs, flag: int) (void | errno) = { + wrap_return(syscall3(SYS___fstatvfs190, fd: u64, + _statvfs: uintptr: u64, flag: u64))?; +}; + export fn futimens(fd: int, ts: *[2]timespec) (void | errno) = { wrap_return(syscall2(SYS_futimens, fd: u64, ts: uintptr: u64))?; @@ -150,6 +155,11 @@ export fn sysctl(name: []const u32, oldp: nullable *opaque, oldlenp: nullable *s newp: uintptr: u64, newlen: u64))?; }; +export fn unlink(path: path) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall1(SYS_unlink, path: uintptr: u64))?; +}; + export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = { let path = kpath(path)?; wrap_return(syscall3(SYS_unlinkat, diff --git a/rt/+netbsd/types.ha b/rt/+netbsd/types.ha @@ -138,11 +138,85 @@ export type stat = struct { st_spare: [2]u32, }; +export type fsid_t = struct { + __fsid_val: [2]u32, +}; + +export def VFS_NAMELEN: int = 32; +export def VFS_MNAMELEN: int = 1024; + +export type statvfs = struct { + // copy of mount exported flags + f_flag: u64, + // file system block size + f_bsize: u64, + // fundamental file system block size + f_frsize: u64, + // optimal file system block size + f_iosize: u64, + + // The following are in units of f_frsize + + // number of blocks in file system, + f_blocks: u64, + // free blocks avail in file system + f_bfree: u64, + // free blocks avail to non-root + f_bavail: u64, + // blocks reserved for root + f_bresvd: u64, + + // total file nodes in file system + f_files: u64, + // free file nodes in file system + f_ffree: u64, + // free file nodes avail to non-root + f_favail: u64, + // file nodes reserved for root + f_fresvd: u64, + + // count of sync reads since mount + f_syncreads: u64, + // count of sync writes since mount + f_syncwrites: u64, + + // count of async reads since mount + f_asyncreads: u64, + // count of async writes since mount + f_asyncwrites: u64, + + // NetBSD compatible fsid + f_fsidx: fsid_t, + // Posix compatible fsid + f_fsid: u64, + // maximum filename length + f_namemax: u64, + // user that mounted the file system + f_owner: uid_t, + __pad0: u32, + + // spare space + f_spare: [4]u64, + + // fs type name + f_fstypename: [VFS_NAMELEN]u8, + // directory on which mounted + f_mntonname: [VFS_MNAMELEN]u8, + // mounted file system + f_mntfromname: [VFS_MNAMELEN]u8, + // disk label name if avail + f_mntfromlabel: [VFS_MNAMELEN]u8, +}; + export type dirent = struct { - d_fileno: ino_t, // file number of entry - d_reclen: u16, // length of this record - d_namlen: u16, // length of d_name - d_type: u8, // file type, see below + // file number of entry + d_fileno: ino_t, + // length of this record + d_reclen: u16, + // length of d_name + d_namlen: u16, + // file type, see below + d_type: u8, d_name: [NAME_MAX + 1]u8, }; @@ -274,22 +348,38 @@ export type ptmget = struct { }; export type rusage = struct { - ru_utime: timeval, // user time used - ru_stime: timeval, // system time used - ru_maxrss: i64, // max resident set size - ru_ixrss: i64, // integral shared memory size - ru_idrss: i64, // integral unshared data " - ru_isrss: i64, // integral unshared stack " - ru_minflt: i64, // page reclaims - ru_majflt: i64, // page faults - ru_nswap: i64, // swaps - ru_inblock: i64, // block input operations - ru_oublock: i64, // block output operations - ru_msgsnd: i64, // messages sent - ru_msgrcv: i64, // messages received - ru_nsignals: i64, // signals received - ru_nvcsw: i64, // voluntary context switches - ru_nivcsw: i64, // involuntary " + // user time used + ru_utime: timeval, + // system time used + ru_stime: timeval, + // max resident set size + ru_maxrss: i64, + // integral shared memory size + ru_ixrss: i64, + // integral unshared data " + ru_idrss: i64, + // integral unshared stack " + ru_isrss: i64, + // page reclaims + ru_minflt: i64, + // page faults + ru_majflt: i64, + // swaps + ru_nswap: i64, + // block input operations + ru_inblock: i64, + // block output operations + ru_oublock: i64, + // messages sent + ru_msgsnd: i64, + // messages received + ru_msgrcv: i64, + // signals received + ru_nsignals: i64, + // voluntary context switches + ru_nvcsw: i64, + // involuntary " + ru_nivcsw: i64, }; export def DT_UNKNOWN: u8 = 0; @@ -324,6 +414,7 @@ export def O_EXEC: int = 0x00040000; export def O_TTY_INIT: int = 0x00080000; export def O_CLOEXEC: int = 0x00400000; export def O_DSYNC: int = 0x01000000; +export def O_RSYNC: int = 0x00020000; export def AT_FDCWD: int = -100; export def AT_EACCESS: int = 0x0100; @@ -332,13 +423,63 @@ export def AT_SYMLINK_FOLLOW: int = 0x0400; export def AT_REMOVEDIR: int = 0x0800; export def AT_RESOLVE_BENEATH: int = 0x2000; -export def S_IFIFO: mode_t = 0o010000; -export def S_IFCHR: mode_t = 0o020000; -export def S_IFDIR: mode_t = 0o040000; -export def S_IFBLK: mode_t = 0o060000; -export def S_IFREG: mode_t = 0o100000; -export def S_IFLNK: mode_t = 0o120000; -export def S_IFSOCK: mode_t = 0o140000; +// set user id on execution +export def S_ISUID: u64 = 0o004000; +// set group id on execution +export def S_ISGID: u64 = 0o002000; +// sticky bit +export def S_ISTXT: u64 = 0o001000; +// RWX mask for owner +export def S_IRWXU: u64 = 0o000700; +// R for owner +export def S_IRUSR: u64 = 0o000400; +// W for owner +export def S_IWUSR: u64 = 0o000200; +// X for owner +export def S_IXUSR: u64 = 0o000100; +export def S_IREAD: u64 = S_IRUSR; +export def S_IWRITE: u64 = S_IWUSR; +export def S_IEXEC: u64 = S_IXUSR; +// RWX mask for group +export def S_IRWXG: u64 = 0o000070; +// R for group +export def S_IRGRP: u64 = 0o000040; +// W for group +export def S_IWGRP: u64 = 0o000020; +// X for group +export def S_IXGRP: u64 = 0o000010; +// RWX mask for other +export def S_IRWXO: u64 = 0o000007; +// R for other +export def S_IROTH: u64 = 0o000004; +// W for other +export def S_IWOTH: u64 = 0o000002; +// X for other +export def S_IXOTH: u64 = 0o000001; +// type of file mask +export def S_IFMT: u64 = 0o170000; +// named pipe (fifo) +export def S_IFIFO: u64 = 0o010000; +// character special +export def S_IFCHR: u64 = 0o020000; +// directory +export def S_IFDIR: u64 = 0o040000; +// block special +export def S_IFBLK: u64 = 0o060000; +// regular +export def S_IFREG: u64 = 0o100000; +// symbolic link +export def S_IFLNK: u64 = 0o120000; +// save swapped text even after use +export def S_ISVTX: u64 = 0o001000; +// socket +export def S_IFSOCK: u64 = 0o140000; +// whiteout +export def S_IFWHT: u64 = 0o160000; +// Archive state 1, ls -l shows 'a' +export def S_ARCH1: u64 = 0o200000; +// Archive state 2, ls -l shows 'A' +export def S_ARCH2: u64 = 0o400000; export def MAP_SHARED: uint = 0x0001; export def MAP_PRIVATE: uint = 0x0002; @@ -492,10 +633,28 @@ export def RLIMIT_NPTS: int = 11; export def RLIMIT_SWAP: int = 12; export def RLIMIT_KQUEUES: int = 13; export def RLIMIT_UMTXP: int = 14; -export def RLIMIT_NTHR: int = 11; // number of threads +// number of threads +export def RLIMIT_NTHR: int = 11; export def SHUT_RD: int = 0; export def SHUT_WR: int = 1; export def SHUT_RDWR: int = 2; -export def NODEV: int = -1; // non-existent device +// non-existent device +export def NODEV: int = -1; + +// synchronously wait for I/O to complete +export def MNT_WAIT: int = 1; +// start all I/O, but do not wait for it +export def MNT_NOWAIT: int = 2; +// push data not written by filesystem syncer +export def MNT_LAZY: int = 3; + +// Efficient memory file-system +export def MOUNT_TMPFS = "tmpfs"; +export def MOUNT_SHMFS = MOUNT_TMPFS; + +// Shared memory objects are supported using tmpfs. +export def SHMFS_DIR_PATH = "/var/shm"; +export def SHMFS_DIR_MODE = (S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO); +export def SHMFS_OBJ_PREFIX = ".shmobj_";