Retrieve php resources from native code
phpbg opened this issue · 2 comments
Hi,
let's say I want to use open()
from fcntl.h
If I load this into FFI:
int open(const char *pathname, int flags);
then php see the result as an integer, while it is a file descriptor.
Am I wrong?
Is there a way to handle file descriptors?
TL;DR: Probably no. It doesn't really make sense to support this as a built-in part of FFI, but there are other ways to do this.
Resources are too complex to provide any kind of (useful) generic support for them - they are essentially objects without a public API, wrapping arbitrary data structures up in an opaque ball of state. For any conceivable use case you would always need a lot of definitions on top in order to access the underlying data.
However...
The specific case you use as an example can (probably) already be handled with existing core PHP functionality. If you know the number of an fd, you can obtain a stream resource referencing it via the php://
wrapper. This mechanism has some limitations - it is only available in the CLI SAPI, and it is not strictly true to say it gives you direct access to the fd as it is dup()
ed for the result, so e.g. calling fclose()
on the stream resource will not close the original fd - but in the vast majority of cases it can be managed to produce the desired behaviour. A small example can be seen below:
// Create a stream wrapping fd#1 - the mode is ignored as the descriptor already exists
$fp = fopen('php://fd/1', 'w');
// Usually fd#1 is stdout, so this will output to the console
fwrite($fp, 'Hello world');
...unfortunately though, I'm not aware of any way to do the reverse of the code above, i.e. you can't get the fd number from an existing stream resource. There have been one or two occasions in the past where I have wanted this for something, so it might be worth adding some way to access that information - but again this would not be a matter for FFI, I would suggest something more along the lines of an extra element in the array returned by stream_get_meta_data()
for the STDIO
stream type.
Hi, thanks for your answer.
I wanted to play with ioctl, but I guess PHP is not ready for this...