I've dug more into the code and came up with something a bit nicer than what I originally described. Feel free to look at the changes (comments and suggestions are always welcome).

My basic assumption is that the underlying CFFI-SYS functions like %foreign-funcall and defcfun-helper-forms would return two values whenever defcfun or foreign-funcall is configured to return errno. The first value is the foreign call return value, and the second is errno. errno is then captured to be passed to the user's structure, and the foreign call return value is propagated further.

Here's a sample of how it looks:

CL-USER> (defparameter errno-object (cffi:make-errno :value 0))
ERRNO-OBJECT

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 errno-object -1 -1 -1)
-1

CL-USER> errno-object
#S(CFFI::ERRNO :VALUE 22)

More:

CL-USER> (defparameter errno-object (cffi:make-errno :value 0))
ERRNO-OBJECT

CL-USER> (cffi:foreign-funcall ("getenv" :errno errno-object) :string "SHELL" :string+ptr)
("/bin/bash" 140735646882874)

CL-USER> errno-object
#S(CFFI::ERRNO :VALUE 0)

Last one:

CL-USER> (defparameter errno-object (cffi:make-errno :value 0))
ERRNO-OBJECT

CL-USER> (cffi:defcfun ("printf" :errno t) :int
                 (control :string)
                 &rest)
PRINTF

CL-USER> (printf errno-object "%s %s" :string "hi" :string "bob")
6

CL-USER> errno-object
#S(CFFI::ERRNO :VALUE 0)




On Thu, Aug 8, 2013 at 11:37 PM, Luís Oliveira <luismbo@gmail.com> wrote:
Felix Filozov <ffilozov@gmail.com> writes:

> Looking into Allegro CL SMP's manual, there's a macro called
> with-delayed-interrupts, which should prevent interrupts and GC from
> running. However, the wrong errno was still returned when I used this
> macro. I will ask Franz if such a macro exists.

What's your test case like?


> I started exploring your second suggestion. I created an errno
> defstruct (this is what the user passes), in the CFFI package, and I
> tried passing that structure to the CFFI-SYS layer to be modified, but
> then I realized that CFFI-SYS doesn't know anything about the CFFI
> package so it can't modify the structure. So I'm passing a function to
> CFFI-SYS, which gets called with the returned errno value as an
> argument. I don't know if I like this callback mechanism.

Seems a bit heavy handed, yeah. We can split cffi-sys in two files: a
shared file (with the package define and perhaps that structure
definition) and an implementation-specific file.


> Also, while reading through the code I noticed that there's some edge
> cases that would need to be handled. For example %defcfun may make a
> call to foreign-funcall if the argument types and the returns types
> are considered call-by-value. What does that mean?

We've recently added support for passing structures by value. When that
functionality is needed, we use libffi for invoking the foreign
function. I have no idea how we can reliably get errno in that case.


> I also don't quite understand what entry-vec is, if that's something
> that can be ignored for now.

I don't remember the details, but doc/allegro-internals.txt has some
info about it.

Cheers,

--
Luís Oliveira
http://kerno.org/~luis