Odin icon indicating copy to clipboard operation
Odin copied to clipboard

add shm_open and shm_unlink syscalls for darwin

Open beaumccartney opened this issue 11 months ago • 11 comments

useful for virtual memory tricks involving mapping multiple VPNs to the same physical page

I added a wrapper similar to the wrapper for the open syscall. Because both wrappers want to pull open flags from the bitset in the same way, I factored that out into a separate function and had both wrappers use that instead.

beaumccartney avatar Mar 15 '24 14:03 beaumccartney

ahh good catch, perms weren't set. I tried setting perms with fchmod but didn't work. I suspect I'm missing something so I'll take another look when I'm available again.

beaumccartney avatar Mar 15 '24 23:03 beaumccartney

I suggest just using fchmod as i did with the open syscall wrapper

Platin21 avatar Mar 16 '24 10:03 Platin21

I tried it, and I just committed it now. With this repro I still just get zero when I check the permissions with fstat.

// NOTE: sys_shm_open attempts to change the permissions of the descriptor with fchmod
package main

main :: proc() {
    fd, ok := darwin.sys_shm_open("mydesc", {.CREAT, .RDWR}, darwin.PERMISSION_ALL_ALL)

    stat: darwin.stat
    thing := darwin.syscall_fstat(fd, &stat)

    fmt.println("fstat return:", thing)
    fmt.println("permissions: ", stat.st_mode)
}


import "core:fmt"
import "core:sys/darwin"

for me outputs

fstat return: 0
permissions:  0

EDIT: didn't refresh and see that you approved the changes. I'm still not able to actually get a fd from shm_open with different permissions though.

beaumccartney avatar Mar 16 '24 18:03 beaumccartney

I changed the check on fchmod from != -1 to == 0 and how it's failing.

Tried doing it in my own code instead and printing the result and I got syscall_fchmod to return 22. But checking the fchmod manpage it only returns 0 or -1 and sets errno.

I'm guessing the syscall wrappers return errno if it's set cause when I pass a zero file descriptor to fchmod I get a return of nine (errno for a bad file descriptor).

Should the checks around syscall_fchmod check ==0 instead of != -1 (also in sys_open)? I think that a non-zero return is an error

EDIT: didn't refresh and see that you approved the changes. I'm still not able to actually get a fd from shm_open with different permissions though.

beaumccartney avatar Mar 16 '24 18:03 beaumccartney

So you still can create the shm? So what is it returning i would have expected that it would give correct permissions if you use fchmod. I must be honest here I didn't check the error conditions of the sys_open. The return should be zero I think I just reapplied the pattern from sys_open..

It should actually allow setting the permissions on a shm object or at least there isn't anything that would prevent that. Especially on the unix side fchmod should be fine.

Platin21 avatar Mar 16 '24 19:03 Platin21

If I check that syscall_fchmod == 0, everything fails cause the pattern makes everything fail. If I don't have the fchmod call at all, I can get and use a shm. I even implemented a ring buffer by mapping consecutive slices of virtual address space to the same shm before I made this PR (and before I checked anything with perms or tried fchmod). Just can't get the correct report from fstat for some reason.

I think the check should also be == 0 in sys_open because syscall_fchmod apparently can return > 0, and a >0 return is an error (I think).

beaumccartney avatar Mar 17 '24 01:03 beaumccartney

So you can or you can't shm_open the same name again in two different programs? Else I simply guess that macOS does have a slight bug with the permissions.

Platin21 avatar Mar 17 '24 19:03 Platin21

Sorry I misunderstood you. I can open the shm in two different programs. I ran the below repro in one terminal with just odin run . and in another terminal with odin run . -out:somethingelse at the same time, and both opened with shm_open successfully.

package main

main :: proc() {
    fd, ok := darwin.sys_shm_open("mydesc", {.CREAT, .RDWR}, {})
    fmt.println(fd, ok)

    for {
        time.sleep(1)
    }
}


import "core:fmt"
import "core:sys/darwin"
import "core:time"

I hope that's what you meant by shm_open the same name in two different programs

Should something happen with syscall_fchmod not actually working? Should it be documented somewhere (ig it is here) that it's failing in case the underlying bug gets fixed? Should it not be called at all? I don't really know but imo it's worth thinking about.

beaumccartney avatar Mar 18 '24 23:03 beaumccartney

Ahh the reason why i mentioned it was mostly because one could use this to make a shm readonly for external. But i suspect its basically not worth it. So maybe just öeave a comment there that the permissions are f** and do not work or at least can‘t be gathered. Otherwise if the files can be opend on both programs leave it.

Platin21 avatar Mar 19 '24 07:03 Platin21

k I added a note abt it

btw I tried doing the same thing in c and had the exact same issue (except errno was set instead of a >0 return obviously) so I'm pretty sure the bug's not on odin's end.

beaumccartney avatar Mar 19 '24 15:03 beaumccartney

is there anything else I need to do? @Platin21

beaumccartney avatar Apr 09 '24 01:04 beaumccartney