I worked out a basic implementation for a thread-local errno<https://github.com/ffilozov/cffi/compare/thread-local-errno>. Bordeaux-threads has been added as a dependency as well as two extra functions: cffi:set-errno and cffi:get-errno.
This is a much cleaner interface than passing an object, and the generated function doesn't need to have an extra parameter. Sample: CL-USER> (cffi:defcfun ("socket" :errno t) :int (a :int) (b :int) (c :int)) Warning: :call-direct ignored because :error-value specified. SOCKET CL-USER> (socket -1 -1 -1) -1 CL-USER> (cffi:get-errno) 22 T The implementation uses locking, so its efficiency could improved. I'm interested in your suggestions on how to do that. On Thu, Aug 8, 2013 at 4:29 AM, Daniel Herring <dherr...@tentpost.com>wrote: > Hi Felix, > > Errno is a particularly tricky beast. It is a thread-local "global" that > is modified by a large number of system calls and library functions. Code > must be careful to check it before another such call is made. I could > easily imagine a stop-the-world GC accidentally modifying errno if errno is > not checked "atomically" with the function call. > > Also errno is very lightweight. An extra foreign call to check it could > easily dwarf the cost of the check. Errno is a "hidden" return parameter, > much like the second position in a multiple-value return. > > Thus the Allegro semantics of returning errno as a second value seem > reasonable to me. > > As you suggested, CFFI could provide a default errno implementation for > CLs that have different native semantics. > > - Daniel > >