|
From: | Barath Aron |
Subject: | Re: fopen()-pclose() bug in install-info |
Date: | Tue, 9 Feb 2021 21:10:28 +0100 |
On 2/9/21 6:11 PM, Gavin Smith wrote:
On Fri, Jan 29, 2021 at 01:41:22PM +0100, Barath Aron wrote:Hello, I ran into a bug in the "install-info" program, where the "dir" file is opened with fopen(), and it was closed with pclose(). That's why "install-info" hangs on the OS I use. The path in the code is clear. install-info/install-info.c: 910: f = open_possibly_compressed_file (...) 700: f = fopen (*opened_filename, FOPEN_RBIN); # this might be executed, but won't make any difference 882: f = freopen (*opened_filename, "r", f); 888: return f; 939: pclose(f); I was able to get this work with the attached patch file, based on the comments and the code around it.I didn't completely follow the problem and your fix. When exactly does install-info hang and what OS do you use? I think your fix stops pclose being called using the condition that f != stdin in the readfile function but it doesn't look like the right place for this. Relevant commits in the git history are 2d03d088d9 and 3c795d1bcf and this message https://lists.gnu.org/archive/html/bug-texinfo/2015-02/msg00074.html
The code path I wrote is the trace of the program, I didn't made it up. It first opened a regular, non-compressed file with fopen() [this was in line 700], then it would freopen()ed [line 882, but it won't make any difference], then closed the fopen()ed file with pclose() [line 939]. And per-definition, you can't pclose() a FILE opened with fopen(). It is undefined behavior, libc is "allowed" to wait for something which will not happen. POSIX spec says: "If the argument stream to pclose() is not a pointer to a stream created by popen(), the result of pclose() is undefined." So, on Linux and on some other OSs this case works by mistake, but it is not required.
My patch is just a messy workaround to get rid of the problem (closing a fopen()ed file with pclose()). Yes, my intention was clearly to stop pclose() being called. If you take a look at the code, the only path where pclose() is not called is when it was a regular, non-compressed file.
I use Threos OS, which is a Unix-like system, which is currently under development. It's libc is based on musl, but the Linux-specific stuff was reimplemented.
Aron
[Prev in Thread] | Current Thread | [Next in Thread] |