From 44167800ad7cf7fd8824776f79c48d886808ff1a Mon Sep 17 00:00:00 2001 From: Beau McCartney Date: Fri, 15 Mar 2024 08:08:37 -0600 Subject: [PATCH 1/6] darwin: syscall wrappers for shm_open() and shm_unlink() --- core/sys/darwin/xnu_system_call_wrappers.odin | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/sys/darwin/xnu_system_call_wrappers.odin b/core/sys/darwin/xnu_system_call_wrappers.odin index b69877cc9..814afe475 100644 --- a/core/sys/darwin/xnu_system_call_wrappers.odin +++ b/core/sys/darwin/xnu_system_call_wrappers.odin @@ -421,3 +421,11 @@ syscall_fchdir :: #force_inline proc "contextless" (fd: c.int, path: cstring) -> syscall_getrusage :: #force_inline proc "contextless" (who: c.int, rusage: ^RUsage) -> c.int { return cast(c.int) intrinsics.syscall(unix_offset_syscall(.getrusage), uintptr(who), uintptr(rusage)) } + +syscall_shm_open :: #force_inline proc "contextless" (name: cstring, oflag: u32, mode: u32) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.shm_open), transmute(uintptr)name, uintptr(oflag), uintptr(mode)) +} + +syscall_shm_unlink :: #force_inline proc "contextless" (name: cstring) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.shm_unlink), transmute(uintptr)name) +} From cf949e541f9a5abd1785c2a382f1de5b706dfd8b Mon Sep 17 00:00:00 2001 From: Beau McCartney Date: Fri, 15 Mar 2024 08:11:10 -0600 Subject: [PATCH 2/6] helper function to convert Open_Flags bitset to a u32 - analagous to _sys_permission_mode() - uses the already-existing conversion logic in sys_open() --- core/sys/darwin/xnu_system_call_helpers.odin | 23 ++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/core/sys/darwin/xnu_system_call_helpers.odin b/core/sys/darwin/xnu_system_call_helpers.odin index 753f7f058..06cf26178 100644 --- a/core/sys/darwin/xnu_system_call_helpers.odin +++ b/core/sys/darwin/xnu_system_call_helpers.odin @@ -87,6 +87,29 @@ _sys_permission_mode :: #force_inline proc (mode: Permission) -> u32 { return cflags } +_sys_open_mode :: #force_inline proc(mode: Open_Flags) -> u32 { + cflags : u32 = 0 + + cflags |= OPEN_FLAG_RDONLY * u32(Open_Flags.RDONLY in mode) + cflags |= OPEN_FLAG_WRONLY * u32(Open_Flags.WRONLY in mode) + cflags |= OPEN_FLAG_RDWR * u32(Open_Flags.RDWR in mode) + cflags |= OPEN_FLAG_NONBLOCK * u32(Open_Flags.NONBLOCK in mode) + cflags |= OPEN_FLAG_CREAT * u32(Open_Flags.CREAT in mode) + cflags |= OPEN_FLAG_APPEND * u32(Open_Flags.APPEND in mode) + cflags |= OPEN_FLAG_TRUNC * u32(Open_Flags.TRUNC in mode) + cflags |= OPEN_FLAG_EXCL * u32(Open_Flags.EXCL in mode) + cflags |= OPEN_FLAG_SHLOCK * u32(Open_Flags.SHLOCK in mode) + cflags |= OPEN_FLAG_EXLOCK * u32(Open_Flags.EXLOCK in mode) + cflags |= OPEN_FLAG_DIRECTORY * u32(Open_Flags.DIRECTORY in mode) + cflags |= OPEN_FLAG_NOFOLLOW * u32(Open_Flags.NOFOLLOW in mode) + cflags |= OPEN_FLAG_SYMLINK * u32(Open_Flags.SYMLINK in mode) + cflags |= OPEN_FLAG_EVTONLY * u32(Open_Flags.EVTONLY in mode) + cflags |= OPEN_FLAG_CLOEXEC * u32(Open_Flags.CLOEXEC in mode) + cflags |= OPEN_FLAG_NOFOLLOW_ANY * u32(Open_Flags.NOFOLLOW_ANY in mode) + + return cflags +} + @(private) clone_to_cstring :: proc(s: string, allocator: runtime.Allocator, loc := #caller_location) -> cstring { c := make([]byte, len(s)+1, allocator, loc) From 56a29685b4407c73f66e03cedabbcf983640774d Mon Sep 17 00:00:00 2001 From: Beau McCartney Date: Fri, 15 Mar 2024 08:16:40 -0600 Subject: [PATCH 3/6] darwin: sys_shm_open() helper wraps syscall_shm_open() in the same way that sys_open() wraps syscall_open() --- core/sys/darwin/xnu_system_call_helpers.odin | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/sys/darwin/xnu_system_call_helpers.odin b/core/sys/darwin/xnu_system_call_helpers.odin index 06cf26178..fab212c16 100644 --- a/core/sys/darwin/xnu_system_call_helpers.odin +++ b/core/sys/darwin/xnu_system_call_helpers.odin @@ -206,3 +206,20 @@ sys_lstat :: proc(path: string, status: ^stat) -> bool { cpath: cstring = clone_to_cstring(path, context.temp_allocator) return syscall_lstat(cpath, status) != -1 } + +sys_shm_open :: proc(name: string, oflag: Open_Flags, mode: Permission) -> (c.int, bool) { + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + + cmode: u32 = 0 + cflags: u32 = 0 + cname: cstring = clone_to_cstring(name, context.temp_allocator) + + cflags = _sys_permission_mode(mode) + + cmode = _sys_open_mode(oflag) + + result := syscall_shm_open(cname, cmode, cflags) + state := result != -1 + + return result * cast(c.int)state, state +} From 24f9e16dfd59711edd0d3276360e9a98b120dfd2 Mon Sep 17 00:00:00 2001 From: Beau McCartney Date: Fri, 15 Mar 2024 08:21:48 -0600 Subject: [PATCH 4/6] sys_open() calls _sys_open_mode() to get a permission flags integer _sys_open_mode() does exactly what sys_open() was originally doing inline, I simply factored it into a separate function so that other wrappers could call it (similar to _sys_permission_mode()) --- core/sys/darwin/xnu_system_call_helpers.odin | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/core/sys/darwin/xnu_system_call_helpers.odin b/core/sys/darwin/xnu_system_call_helpers.odin index fab212c16..815f62466 100644 --- a/core/sys/darwin/xnu_system_call_helpers.odin +++ b/core/sys/darwin/xnu_system_call_helpers.odin @@ -128,22 +128,7 @@ sys_open :: proc(path: string, oflag: Open_Flags, mode: Permission) -> (c.int, b cflags = _sys_permission_mode(mode) - cmode |= OPEN_FLAG_RDONLY * u32(Open_Flags.RDONLY in oflag) - cmode |= OPEN_FLAG_WRONLY * u32(Open_Flags.WRONLY in oflag) - cmode |= OPEN_FLAG_RDWR * u32(Open_Flags.RDWR in oflag) - cmode |= OPEN_FLAG_NONBLOCK * u32(Open_Flags.NONBLOCK in oflag) - cmode |= OPEN_FLAG_CREAT * u32(Open_Flags.CREAT in oflag) - cmode |= OPEN_FLAG_APPEND * u32(Open_Flags.APPEND in oflag) - cmode |= OPEN_FLAG_TRUNC * u32(Open_Flags.TRUNC in oflag) - cmode |= OPEN_FLAG_EXCL * u32(Open_Flags.EXCL in oflag) - cmode |= OPEN_FLAG_SHLOCK * u32(Open_Flags.SHLOCK in oflag) - cmode |= OPEN_FLAG_EXLOCK * u32(Open_Flags.EXLOCK in oflag) - cmode |= OPEN_FLAG_DIRECTORY * u32(Open_Flags.DIRECTORY in oflag) - cmode |= OPEN_FLAG_NOFOLLOW * u32(Open_Flags.NOFOLLOW in oflag) - cmode |= OPEN_FLAG_SYMLINK * u32(Open_Flags.SYMLINK in oflag) - cmode |= OPEN_FLAG_EVTONLY * u32(Open_Flags.EVTONLY in oflag) - cmode |= OPEN_FLAG_CLOEXEC * u32(Open_Flags.CLOEXEC in oflag) - cmode |= OPEN_FLAG_NOFOLLOW_ANY * u32(Open_Flags.NOFOLLOW_ANY in oflag) + cmode = _sys_open_mode(oflag) result := syscall_open(cpath, cmode, cflags) state := result != -1 From 1758bd683e8e3dbceaa79e0cfc5da437f48be87e Mon Sep 17 00:00:00 2001 From: Beau McCartney Date: Sat, 16 Mar 2024 12:13:00 -0600 Subject: [PATCH 5/6] sys_shm_open: fchmod the returned descriptor to get correct perms this doesn't happen by default --- core/sys/darwin/xnu_system_call_helpers.odin | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/sys/darwin/xnu_system_call_helpers.odin b/core/sys/darwin/xnu_system_call_helpers.odin index 815f62466..e253a0cd9 100644 --- a/core/sys/darwin/xnu_system_call_helpers.odin +++ b/core/sys/darwin/xnu_system_call_helpers.odin @@ -206,5 +206,9 @@ sys_shm_open :: proc(name: string, oflag: Open_Flags, mode: Permission) -> (c.in result := syscall_shm_open(cname, cmode, cflags) state := result != -1 + if state && cflags != 0 { + state = (syscall_fchmod(result, cflags) != -1) + } + return result * cast(c.int)state, state } From 43e8da2e067c6a2ecbc663bfbae0eafe67dc41e1 Mon Sep 17 00:00:00 2001 From: Beau McCartney Date: Tue, 19 Mar 2024 09:36:49 -0600 Subject: [PATCH 6/6] shm_open: comment with notes abt permissions --- core/sys/darwin/xnu_system_call_helpers.odin | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/sys/darwin/xnu_system_call_helpers.odin b/core/sys/darwin/xnu_system_call_helpers.odin index e253a0cd9..19e38ce56 100644 --- a/core/sys/darwin/xnu_system_call_helpers.odin +++ b/core/sys/darwin/xnu_system_call_helpers.odin @@ -206,6 +206,11 @@ sys_shm_open :: proc(name: string, oflag: Open_Flags, mode: Permission) -> (c.in result := syscall_shm_open(cname, cmode, cflags) state := result != -1 + // NOTE(beau): Presently fstat doesn't report any changed permissions + // on the file descriptor even with this fchmod (which fails with a + // non-zero return). I can also reproduce this with the syscalls in c + // so I suspect it's not odin's bug. I've left the fchmod in case the + // underlying issue is fixed. if state && cflags != 0 { state = (syscall_fchmod(result, cflags) != -1) }