Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's the right way to create a stat struct to pass into a function? #1043

Open
sj26 opened this issue Aug 12, 2023 · 1 comment
Open

What's the right way to create a stat struct to pass into a function? #1043

sj26 opened this issue Aug 12, 2023 · 1 comment

Comments

@sj26
Copy link

sj26 commented Aug 12, 2023

We're trying to adopt the lovely ffi-libarchive maintained by @chef, but it's using ffi-inliner to grab a stat struct to pass into one of the methods. I'd like some advice on how to grab a pointer to a stat struct and pass it into a method in an idiomatic way 🙏

libarchive can be used to write new archives. It can copy the stat of a file on a local filesystem. So ffi-libarchive is doing this via some inline C:

https://github.com/chef/ffi-libarchive/blob/7dd3c6b2c5a5679a4fc8ba4a1194170a6d8f0ff0/lib/ffi-libarchive/stat.rb

https://github.com/chef/ffi-libarchive/blob/7dd3c6b2c5a5679a4fc8ba4a1194170a6d8f0ff0/lib/ffi-libarchive/entry.rb#L202-L216

https://github.com/chef/ffi-libarchive/blob/7dd3c6b2c5a5679a4fc8ba4a1194170a6d8f0ff0/lib/ffi-libarchive/archive.rb#L199

I don't think the inline C would be necessary if we knew the size of the stat struct. The problem is that is platform dependent, etc.

But Ruby already knows the size of the struct, in File::Stat.

https://github.com/ruby/ruby/blob/v3_2_2/file.c#L488

I can't help but feel like there must be some way to do File.stat(...) # => a File::Stat and pass that into an FFI function as a pointer. It just needs a way to do TypedData_Get_Struct(self, struct stat, &stat_data_type, st) into an FFI::Pointer.

Is there a good way to do this? MappedType smells useful, but I don't really know how to make it all work.

I also tried grabbing the object_id, casting it to a pointer (object_id << 1), then adding a calculated offset into the RTypedData .. but I can't quite get it to work, and it feels pretty unsafe.

I'd happily build a little C extension that teaches FFI how to turn File::Stat instances into pointers if I could figure out how 😅

@sj26
Copy link
Author

sj26 commented Aug 12, 2023

I got a little further mysql -- I have a C extension which can sniff a pointer into the File::Stat object:

sj26/ffi-stat@413e3b0

and it sorta works:

image

It's really rough, reaching in ways it shouldn't, and needs many more guards. But .. it works.

I'd really love to avoid the need for a C extension. Is this sort of thing possible with just FFI?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant