FFI: 'file' size of a non-file file descriptor

I'm currently playing with shared memory spaces via the FFI, looking into shm_open and mmap.
After obtaining a file descriptor fd corresponding to an existing such space, I want to find out the underlying 'file' size. However, it's not an actual file in the file system so there is no associated file-system path — as far as I understand.

If possible, I would really prefer to avoid writing a binding to fstat and its struct, in particular because it must have been done already for Racket/ChezScheme.

Unfortunately, Racket's file-size is only for paths on the system, not file descriptors nor file-stream-port (otherwise file-descriptor->unsafe-port would have worked).

Any idea?

Hm, I think I might be able to use lseek instead (save position with SEEK_CUR, get position of the end with SEEK_END, restore position with SEEK_SET). Hopefully this is not too slow compared to fstat.

Please let me know if that's a bad idea :grimacing:

Technically, shared memory objects ARE in the file system - under /dev/shm ... but typically you are not able to access them AS files.

I would be worried a little about trusting lseek - it may work currently, but even if it does, there is no guarantee that it will continue to work in the future. Unfortunately the only /documented/ method to find the size of a memory object is fstat.

Since, as you noted, there must already be a binding to fstat, I would try to find it and see if I could use it directly. Obviously YMMV.

Can you expand on why there is no guarantee?
man lseek says:

Isn't that a documented version of "file size in bytes"?

I don't think there's a way to get at the existing fstat call, but I'll add port-file-stat to v8.16.0.6.

2 Likes

Shared memory objects are a kind of "special" file. You can open and close and stat special files, but nothing else is guaranteed to work.

1 Like

Awesome, thank you Matthew!

Oh right, I just saw this: