On 08/07/2013 10:44 AM, Luís Oliveira wrote:
It would look like this: (foreign-funcall ("strlen" :errno t) :string "foo" :int), or (defcfun (strlen "strlen" :errno t) :int (s :string)).
Calling (strlen) would return two values, the return value of the foreign call, and errno.
In some Lisps, the only way to get errno is to make an additional foreign call. Then perhaps that call could be made by CFFI and returns as the second value.
That makes sense. Except for the second value bit because CFFI types can yield more than one value. Alternatives that pop up:
Return it as the first value. (Probably requires some multiple-value-list mangling which might not be acceptable performance-wise?)
Have the foreign function accept an extra errno argument that takes some structure than can be modified with the errno value.
Not quite happy with either. Any other ideas?
Perhaps instead of returning "errno" as an additional value, we could modify an internal global thread-local variable with the value of errno when the function is flagged with ":errno t", and export (cffi:errno) to return the thread's saved errno value? That's how the underlying machinery works at the C level after all.
Of course, then CFFI-SYS needs a portable mechanism for thread-locals...
If I was binding a library that was user-hostile enough to use "errno" as its error reporting mechanism, I'd be tempted to wrap its function calls to pass the error code out with an explicit output parameter. I wonder if there's any way to automate that.
James