On Tue, 2011-04-26 at 00:13 +0200, Mike Pall wrote:
Well, it has a couple of drawbacks. It's hard to avoid fetching
the errno, in case it's not needed. And you can't just include a
header file -- you'd need to fix up all declarations.
If it was an annotation on the headers it might be workable, if a little
ugly, eg
int /*errno*/ open(const char *pathname, int flags);
There would have to be a few variants, like zero it first for a few
calls. Definitely ugly. In terms of fixing up all the declarations, I
dont mind too much, I was thinking of maintaining a public set of
declarations for Linux anyway, as you need all the #define constants
declared anyway for the system calls to be usable, unless you have some
scheme planned to parse these too... I think it is a going to be some
time before you can sanely parse glibc's header files... But I can see
why this is more ugly than an ffi.C.errno that is explicit in the code
and which the compiler knows not to move.
It does seem however that there should be platform dependent methods
though, so maybe it is not necessary. On Linux the code below
(__errno_location() is part of LSB) seems to work fine.
Sadly, this is unreliable. E.g. a memory allocation might happen
inbetween or a hook may be called or the JIT compiler might print
debug info inbetween and so on. All of this may reset errno.
Ah yes of course. Oh well, in the very short term will take a risk on
this, better than no error messages, will just print a caveat...
I have a couple of ideas on how to provide a portable ffi.C.errno
abstraction which doesn't lose its state. But no convincing
solution. And then there's GetLastError() on Windows, too ...
The kernel convention of returning -errno is much nicer, almost tempted
to use a native syscall interface instead!
Justin