Returning errno as a second value

Felix Filozov ffilozov at gmail.com
Fri Aug 9 10:17:30 UTC 2013


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<https://github.com/ffilozov/cffi/commit/e35e949891a0fe5faeca2a0a44050edff99b9f3c>
(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 at gmail.com> wrote:

> Felix Filozov <ffilozov at 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
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20130809/49221525/attachment.html>


More information about the cffi-devel mailing list