Description
Fish version: 3.2.2
, built from source. Platform: Solaris 10, SPARC (64-bit).
After compiling fish on such a platform (where O_CLOEXEC
doesn't exist), running it gives the following output:
zhiayang@sunfire0:~/code/fish-3.2.2/build[1022]$ ./fish
Unable to open the current working directory: Error 0
source: Error encountered while sourcing file '/user/z/zhiayang/code/fish-3.2.2/share/config.fish':
source: Error 0
source: Error encountered while sourcing file '/user/z/zhiayang/code/fish-3.2.2/etc/config.fish':
source: Error 0
zhiayang@<hostname> /home/z/zhiayang/code/fish-3.2.2/build > error: Unable to open a pipe for universal variables using '/var/tmp//fish.zhiayang/fish_universal_variables.notifier': File exists
Clearly, everything is broken, backspacing doesn't work, etc. The files stated actually exist (of course -- the current directory must also exist). What got me investigating was the fact that we have Error 0
, which means no error.
After some printf debugging and digging around, the culprit is here, at fds.cpp:254
:
#ifdef O_CLOEXEC
fd = open(path, flags | O_CLOEXEC, mode);
#else
fd = open(path, flags, mode);
if (fd >= 0 && !set_cloexec(fd)) {
exec_close(fd);
fd = -1;
}
#endif
After looking at the return value of set_cloexec
, it is very obvious that this code path has never been tested and run. set_cloexec()
returns non-zero on error... which causes this function to fail -- when it should have succeeded.
The correct comparison should be set_cloexec(fd) != 0
.