3 ms·
I don't think this behaviour is "peculiar" as the author says it is; why does the error number matter if you know the call succeeded? GetLastError() on Windows
by userbinator 1y ago
I don't think this behaviour is "peculiar" as the author says it is; why does the error number matter if you know the call succeeded? GetLastError() on Windows works similarly, although with the additional weird caveat that (undocumentedly) some functions may set it to 0 on success.
The system call wrappers could all have explicitly set errno to 0 on success, but they didn't.
Because it's plainly unnecessary. It'd be a waste today, and even more so on a PDP-11 in the 1970s.
- aa-jv 1y agoI agree with you, its not so peculiar as one might think. (Disclaimer: been writing software for Unix since before POSIX...) This design choice reflects the POSIX philosophy of minimizing overhead and maximizing flexibility for system programming. Frequent calls to write(), for example, would be hindered by having to reset errno with each call/check of write() return value - especially in cases where a lot of write()'s are queued. Or .. a library function like fopen() might internally call multiple system calls (e.g., open(), stat(), etc.). If one of these calls sets errno but the overall fopen() operation succeeds, the library doesn’t need to clear errno. For instance, fopen() might try to open a file in one mode, fail with an errno of EACCES (permission denied), then retry in another mode and succeed. The final errno value is irrelevant since the call succeeded. This mechanism minimizes overhead by not requiring errno to be reset on success. It allows flexible, efficient implementations of library and system calls and encourages robust programming practices by mandating return-value checks before inspecting errno. It supports complex, retry-based logic in libraries without unnecessary state management - and it preserves potentially useful debugging information. You only care about errno when you know an actual error occurred. Until then, ignore it. This is similar to other systems-level things that can occur in such environments, for example when setting a hard Reset-Reason or Fail-Reason register in static/non-volatile memory somewhere, for later assessment. IMHO, the thing thats most peculiar about this is that folks these days think of it as weird/quaint - when in fact, it makes a lot of sense if you think about it.
- amelius 1y agoDoes Valgrind give a warning when you do check errno after a successful system call?
- aa-jv 1y agoValgrind doesn't specifically (although it might catch side-effects of this bug), but Coverity would, under most conditions (such as having MISRA or CERT checkers enabled), catch it. If its important to you to find these cases, use clang's static analyzer to perform deep source code analysis via scan-build. See also cppcheck and pc-lint, or PVS-Studio, each of which have means by which you can catch this error.
- saagarjha 1y agoI mean, it definitely sucks. It's cute if you look at it as a product of its time but it makes no sense to do things this way anymore.
- aa-jv 1y agoI don't agree with you at all that 'it sucks'. I think it makes perfect sense and works as intended. Plus, we're talking about POSIX here. You don't have a time machine. Shall we argue about just how much POSIX software is out there, working perfectly fine with this technique? Sure, in New Fangled Language De Jour™, return as many tuples as your heart desires. But don't expect POSIX to play along ..
- saagarjha 1y agoIt sucks because people miss error codes, or they overwrite them, or misunderstand what they mean. You read the blog post right? That’s what I’m talking about. I deal with that all the time (maybe more than the average person, to be fair, but still it’s a lot). I don’t really blame the people in 1970 for coming up with this design but it’s 2025 now; we can agree that it has problems. Tape recorders were also a neat idea but I can record a thousand times more on my phone now, often at higher quality. By modern standards, they suck.