[plt-scheme] FFI + errno
At Wed, 9 Dec 2009 11:07:26 -0700, Matthew Flatt wrote:
> [...] Most
> problems like this can be solved with atomic mode, but `errno' is a
> special case. Probably the FFI should provide more direct support for
> getting the right `errno' value.
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. The
value is saved in a Scheme-thread-local way, so you don't have to worry
about explicitly setting atomic mode between the foreign call and the
call to `save-errno'.
For example, a suitable FFI type for the Posix open() function is
(_fun #:save-errno 'posix _string _int -> _int)
After calling open() with that type and before calling any other
foreign function that has `#:save-errno', `(saved-errno)' on the same
thread returns the value that `errno' had right after open() returns.
The 'posix value for `#:save-errno' means to save `errno'. The other
possible option is 'windows, which causes the value of GetLastError()
to be saved, instead. Of course, the 'windows option works only under
Windows.
After adding this feature, it occurred to me that `#:save-errno 'posix'
is needed for most any system call on a Unix-like platform, because a
system call can be interrupted by a signal. As an example, the
`truncate' function in `mzlib/os' uses several system calls; it now
detects interruption by a signal and retries the call.