James Bielman wrote:
>While working through my fancy gettimeofday CFFI example, I've added a
>type translator used as the return type for standard C functions that
>return a negative integer on error and set 'errno'.
A very useful type indeed. I'd like to hear about its design.
Would a result of -1 raise a Lisp error?
[ok, I'm checking the sources myself, "darcs pull" ...]
I think you did TRT by throwing an error in that case. Yet possibly some people might object throwing errors out of "low-level" FFI code, as it requires them to be very careful about freeing all resources...
May I suggest you defined a CLCS condition, so there's
a) a known slot where to get the errno value (instead of pulling it out of a string)
b) a known condition and a possibility to hook in with HANDLER-BIND etc.?
I believe exporting an interface to errno from CFFI will avoid many headaches to users (writing unportable or otherwise broken code to get its value). Please go ahead and include this stuff in the main tree, not examples/.
>(minusp value)
I think you should specifically check for -1. Some functions could return a legal value such large that it overflows an int and becomes negative.
Actually, I wonder whether the DWIM pattern of all these functions shouldn't have been: "it returns an unsigned int, except for (unsigned-int)(-1) which is taken to mean `error'".
E.g. lseek() etc. (although I don't know whether Linux supports files of length >2GB, but lseek is just an example).
BTW, I find the name syscall-result misleading. What about int-or-errno? (Or rather, to keep with my own advice: uint-or-errno)?
Or, like the boolean generic type, write a
(define-foreign-type maybe-errno (&optional (base-type int))?
>Since errno is often a macro expanding to a function, I can't very well
>define it as a foreign global.
It is not, so it would be wrong to do so. errno is a per-thread value on all systems that support threading. In some versions of GLIBC, it's a #define wrapper around a function -- errno_location().
> (defun errno-value () (sb-alien:get-errno))
As soon as errno is there, people will ask for being able to reset it to 0.
>haven't found anything in Allegro CL or CLISP (Jörg?) for this yet.
See clisp/modules/bindings/glibc/linux.lisp as a source of inspiration & read the comments about errno there. It's hairy indeed.
>(I know errno isn't _completely_ portable---at least one OS I use
>regularly, Windows CE, doesn't have it at all [...]
Interesting to know, thanks!
Regards,
Jörg Höhle