Here it is: https://lists.gnu.org/archive/html/bug-bash/2025-06/msg00149...
> Bash forgot to reset errno before the call. For about 30 years, no one noticed
I have to say, this part of the POSIX API is maddening!
99% of the time, you don't need to set errno = 0 before making a call. You check for a non-zero return, and only then look at errno.
But SOMETIMES you need to set errno = 0, because in this case readdir() returns NULL on both error and EOF.
I actually didn't realize this before working on https://oils.pub/
---
And it should go without saying: Oils simply uses libc - we don't need to support system with a broken getcwd()!
Although a funny thing is that I just fixed a bug related to $PWD that AT&T ksh (the original shell, that bash is based on) hasn't fixed for 30+ years too!
(and I didn't realize it was still maintained)
https://www.illumos.org/issues/17442
https://github.com/oils-for-unix/oils/issues/2058
There is a subtle issue with respect to:
1) "trusting" the $PWD value you inherit from another process
2) Respecting symlinks - this is the reason the shell can't just call getcwd() !
if (*p != '/' || stat(p, &st1) || stat(".", &st2) ||
st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
p = 0;
Basically, the shell considers BOTH the inherited $PWD and the value of getcwd() to determine its $PWD. It can't just use one or the other![1] https://github.com/NixOS/nixpkgs/commit/dff0ba38a243603534c9...
It looks easy on the surface to roll down support for any kind of operating system there is, based on auto-detection and then #if HAVE_THIS or #if HAVE_THAT, but it breaks in ways that maybe really hard to untangle later.
I'd rather have a limited set set of configurations targeting specific platforms/flavors, and knowing that no matter how I compile it, I would know what is `#define`-d and what is not, instead of guessing on what the "host" might have.
x0x0•5h ago
For a long time, inode numbers from readdir() had certain semantics. Supporting overlay filesystems required changing those semantics. Piles of software were written against the old semantics; and even some of the most common have not been upgraded.
JdeBP•2h ago
What there are piles of, are softwares that reinvent the C library, all too often in little bits of conditionally-compiled code that have either been reinvented or nicked from some old C library and sit unused in every platform that that application is nowadays ported to. Every time that I see a build log dutifully informing me that it has checked for <string.h> or some other thing that has been standard for 35 years I wonder (a) why that is thought to be necessary in 2025, and (b) what sort of shims would get used if the check ever failed.