Synthetic errno values Lassi Kortela 15 Aug 2020 13:10 UTC
>> As far as I can tell, we could solve the errno problem for SRFI 170 by >> letting the implementor return a foreign-status object with any 'set >> they want (or no 'set at all, which is the same as #f). > > Except this is a tightly specified SRFI. One problem comes with > Shiro's scenario where a C level primitive that's not only called by > SRFI 170 (or in the long term, any of the other POSIX SRFIs that > extend it), and therefore 'set is unknown, although 'errno, which I'm > vastly preferring for the key for the errno raw integer, *can* have a > legitimate value. Why would 'set be unknown in this case? 'set should be driven precisely by the C level. If the C function being called returns its error code in the errno global variable, the 'set should be 'errno for any Scheme exception raised due that C procedure. >> But they must always fill in an 'errno property with the >> errno-equivalent symbol where such is known. > > Urg for namespacing Namespacing is not such a problem when we have the Scheme Registry to help avoid conflicts. The 'errno property would be to contain a (possibly) synthetic errno value. Since it's synthetic, it should be possible to give it to go along with any 'set. > it's probably not much of an imposition > to also report the C define name as a symbol, e.g. 'ENOENT under > whatever key we decide for the POSIX errno 'set. The symbol is primary -- the numerical errno values are less useful as they vary by OS. That's why the synthetic 'errno property should also use symbols rather than numbers. >> We could provide a mapping of Windows API error codes to errno values in >> the sample implementation. Python already does such a mapping in its os >> module I think. > > I really dislike lying to the user. Perhaps justifiable here, but.... It's not lying to the user if the 'errno property is well-known and deliberately designed to be synthetic where the real errno is not available. We could call it 'synthetic-errno for emphasis, but I'm not sure it adds anything. A real errno coming from that C variable would carry '(set errno symbol EINTR number 4) in addition to '(errno EINTR). That's how you can distinguish the real from the fake. However, note that C APIs also fake errno values quite often. By no means is it guaranteed that a C errno comes from the kernel. It can just be a lower-level synthetic errno and we have no way of knowing. It's all relative. >> As explained in another thread, I wouldn't use a 'set property to >> indicate success vs failure from negative vs nonnegative return values. > > Set just tells you the slice of the status and error universe the > object is in, and ideally it'll be registered in the Schemeregistry. > > Unless you use the generic reserved values of 'error or 'status (and > even then you could lie in using them), it says absolutely nothing > about whether the foreign status object represents success or failure, > unless by convention all status in that set are one or the other, which > is true for the POSIX errno 'set. > > If not, that would be the job of a standard key inside it. Perhaps common > enough to be added to the Standard set conventions at the end of SRFI 198. > The 'success? key you suggest below sounds good. WinAPI also has lots of functions that return NULL vs non-NULL (or FALSE vs non-FALSE) to mean failure vs success. There are tons of C APIs based on that principle out there. >> Infinite sets are not enumerable so those are not really error codes. I >> would just return a 'success? property that is #t or #f, which gives the >> same information. If we want to return the precise return value as well, >> I'd return it in 'number (aka 'code) but leave out the 'set unless it >> really belongs to a coherently defined set of particular error values. > > And here I say for the last point you make above, use 'set with either > 'error or 'status as the value to signal that the status object is *not* > one of those "coherently defined set[s] of particular error values." > > Which could actually save a lot of effort by telling people, don't > look to the Schemeregistry to figure out what the additional keys mean, > read the documentation or source code that's using SRFI 198 in this > very generic way. But why have the 'set property when the number is not part of a finite, grovelable set? If all properties default to #f, then 'set #f is a natural way to say that we don't have one. It would however be useful to say that the number which we know nothing about is from libsodium. Would a 'source property separate from 'set make sense? And/or say the name of the C function it came from. Does libsodium use each negative number with the same meaning in all of its functions, or does the same number mean different things when coming from a different function? It's likely we'll amass many useful set-independent properties over the years. This is something I didn't envision when we started design work.