> From: Lassi Kortela <xxxxxx@lassi.io> > Date: Saturday, August 15, 2020 8:10 AM > >>> 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. Heh, that occurred to me after I sent the email you're responding to. A Scheme implementor who wants to have his POSIX calls, for SRFI 170 and/or future SRFIs done by our team, conform to those SRFIs, could in theory change or augment his C level error signaling to always conform to our method, or a proper superset including it. He is after all presumably already reporting the integer errno in one way or another. >>> 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. But while I haven't read for real the proceeding emails, and I recall your having a proposal, the most natural way to partition the files for SRFI 198 errors is by 'set and my previously suggested 'subset (the latter inspired by '(set sqlstate subset postgresql/oracle/etc.)). > 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. John's already covered this in his latest message. This could also be a job for subsets, e.g. '(set posix subset native-windows). As far as I know, POSIX errors always have a specific errno, if not, a return of e.g. NULL for e.g. getpwuid/getpwnam() means this is not an error, I just can't find that user in *this* system, common when moving files from system to system. >> 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. That might not be too much of a burden to an implementor raising an error at the C level, since that's the natural level for establishing the system specific errno number to errno #define name mapping. >>> 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. If we're not starting with a real errno number, if it's truly synthetic, it's a lie. A name less overt than '*synthetic*-errno-name for both real and synthetic would satisfy me on this account. Or combing both my "perhaps justifiable" to lie and subset idea, using a 'windows subset key would signal to the user that he's not getting a "real" errno name. > 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. Ugh, that subverts the desire to make a pure Windows version of e.g. SRFI 170 look and feel as much as possible like one based on a native POSIX interface. > However, note that C APIs also fake errno values quite often. Sure, but I don't have to approve of that ^_^. > 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. "It's all relative" are weasel words for "I'm lying." In the Anglosphere for more than a century when non-scientists glommed onto Einstein's formulation of "Special Relativity", which defined exceptions to Newtonian mechanics (e.g. at speeds approach c, the speed of light). >> [ What about a 'success? key. ] > > 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. Which tells me to rename my tentative "generic-unix-lib" to "generic-c-lib", although I already anticipated it being fine for any libraru that has a binary success return, 0 vs. -1, NULL vs. non-NULL, FALSE or TRUE, it's all the same thing for my purposes, and the exact values are irrelevant for end users. >>> 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. I'm not sure I really need to justify a why, vs. you justifying a why not. Your intuition that this is bad is worth respecting, but for me that's just a clue to then come up with rational arguments, and to then weigh them before making decisions. But I have several, starting with it being the primary key for organizing Schemeregistry. If you don't want to make 'set required, you need a proposal to make that corner of the registry sane for people who put stuff into it and who use it (forgive me if you've already done that and I haven't read it yet, I'm working backwards in the emails). John has a very good one for guards. > 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. Sorry if I haven't been clear, ***libsodium and many other C libraries do not have a number to report as such***. Where I take "number" to be something like an integer errno, or a 5 byte SQLSTATE. We translate its specific UNIX style 0 vs. -1 return into either a binary 'success? value, or just make that subkey (which is optional to define and include in the status object) only return errors. If it never has to report a success as a status object, the UNIX silence is success principle, which is also used as the fundamental error handling paradigm for SRFI 170, 205, etc. > 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? Nope, 0 always means the function succeeded, -1 always means it failed. > 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. That's why there's a limited "set" of them in the SRFI, and as I think I've already stated, there will be an even larger group in Schemeregistry. - Harold