[plt-scheme] FFI + errno

From: Thomas Chust (chust at web.de)
Date: Sun Dec 20 19:30:14 EST 2009

Matthew Flatt schrieb:
> At Sun, 20 Dec 2009 08:56:49 +0100, Thomas Chust wrote:
>> 2009/12/15 Matthew Flatt <mflatt at cs.utah.edu>:
>>> [...]
>>> With the latest in SVN (v4.2.3.5), the `_fun' form of `scheme/foreign'
>>> supports an optional `#:save-errno' specification that makes the FFI
>>> squirrel away the value of `errno' immediately after a foreign call.
>>> The saved value is available through a new `saved-errno' function.
>>> [...]
>> [...]
>> wouldn't it be nicer to have a special kind of output specification
>> for errno values in a _fun form? Since errno is effectively a
>> container for an additional return value from a function, not some
>> kind of permanent state variable, this would seem more natural to me.
>> [...]
> This sounds complicated to me, because cleaning up `errno' handling is
> specific to a particular foreign function.
> [...]


actually I don't propose to add fancy automatic handling of errno
values. I was rather thinking of something very simple like, for
example, replacing your

> [...]
>  (_fun #:save-errno 'posix _bytes
>                     -> (res : _int)
>                     -> (if (equal? res -1)
>                            (error 'errno "~a" (saved-errno)) 
>                            res))
> [...]

with something like

   (_fun _bytes
         -> (res : _int) (errno : (_errno 'posix))
         -> (if (equal? res -1)
                (error 'errno "~a" errno)

where _errno would be a special output type expression.

Of course it would be functionally equivalent, but I think this variant
looks cleaner and is more in the Scheme spirit since it treats the
additional error code output of the function as an output instead of
replicating the strange behaviour of C by storing a function output in a
thread local parameter for no added value.

To me, storing the contents of errno in a thread local location to be
accessed by (saved-errno) seems just as sensible as modifying the
(values ...) special form to return only the first value and to store a
list of all remaining values in a thread local location to be accessed
by (saved-values) — undoubtedly this approach would work, but I don't
think it is an elegant design ;-)

> [...]
> In any case, you could write macros over `_fun' for specific patterns.
> The goal of `#:save-errno' and `saved-errno' is the make the patterns
> possible in the simplest, most general, and most efficient way I could
> find.
> [...]

This would still be possible with my proposed approach. Plus I think not
having to access a thread local storage cell on the Scheme side at least
twice could potentially be a performance advantage.


When C++ is your hammer, every problem looks like your thumb.

Posted on the users mailing list.