On Tue, Apr 15, 2025 at 4:12 PM Grisha Levit <grishale...@gmail.com> wrote: > > On Tue, Apr 15, 2025 at 6:38 PM <jack...@fastmail.fm> wrote: > > > > >> This seems to be fixed if the patch here [1] is _not_ applied when > > >> building the RPM > > > > Can you check, perhaps using strace, whether that problematic patch pushes > > the total amount of bytes written to stdout by grep, writing to /dev/full > > as you > > invoke it, goes from a little below 4096 bytes, in a single write(2) system > > call, > > to trying to write more than 4096 bytes, which likely forces two write > > calls, > > the first 4096 bytes, then the remainder. > > > > Indeed, the `--help' output is 4096 bytes normally and longer after the patch: > > $ ./src/grep --help | wc -c > 4096 > $ patch ... && make -C src grep > $ ./src/grep --help | wc -c > 4122 > > ltrace shows: > > printf("General help using GNU software:"..., > "https://www.gnu.org/gethelp/") = 64 > exit(0 <unfinished ...> > __fpending(0xffff9afe1510, 0, 0xffff9afe2280, 1) = 4096 > fclose(0xffff9afe1510) = -1 > dcgettext(0x41d480, 0x41c418, 5, 0x450000) = 0x41c418 > __errno_location() = 0xffff9b0da760 > error(0, 28, 0x41c318, 0x41c418) = 0xffff9b0ebc90 > > vs > > printf("General help using GNU software:"..., > "https://www.gnu.org/gethelp/") = -1 > exit(0 <unfinished ...> > __fpending(0xffff813f1510, 0, 0xffff813f2280, 1) = 0 > fclose(0xffff813f1510) = 0 > __errno_location() = 0xffff814e9760 > dcgettext(0x41d4a0, 0x41c418, 5, 0x450000) = 0x41c418 > __errno_location() = 0xffff814e9760 > error(0, 0, 0x41c318, 0x41c418) = 0xffff814fac90 > > and gdb (with the patch applied): > > (gdb) n > 58 const bool prev_fail = (ferror (stream) != 0); > (gdb) n > close_stream (stream=0xfffff7ef1510 <_IO_2_1_stdout_>) at > /usr/include/bits/stdio.h:137 > 137 return __ferror_unlocked_body (__stream); > (gdb) n > close_stream (stream=0xfffff7ef1510 <_IO_2_1_stdout_>) at close-stream.c:59 > 59 const bool fclose_fail = (fclose (stream) != 0); > (gdb) n > 69 if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) > (gdb) p prev_fail > $2 = true > (gdb) p fclose_fail > $3 = false > (gdb) p some_pending > $4 = false > (gdb) p errno > $5 = 28 > (gdb) n > 71 if (! fclose_fail) > (gdb) n > 72 errno = 0;
Whoa. Thanks. It looks like this is a >19-year-old bug in stream-close.c Here's a tentative fix -- the ChangeLog entry still lacks details of when it was introduced:
close-stream.diff
Description: Binary data