GNU bug report logs - #77800
grep-3.12: write-error-msg test failure on fedora rawhide (f43)

Previous Next

Package: grep;

Reported by: Jaroslav Škarvada <jskarvad <at> redhat.com>

Date: Mon, 14 Apr 2025 12:56:01 UTC

Severity: normal

Done: Jim Meyering <jim <at> meyering.net>

Bug is archived. No further changes may be made.

Full log


Message #59 received at 77800 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Jim Meyering <jim <at> meyering.net>, Grisha Levit <grishalevit <at> gmail.com>,
 "bug-gnulib <at> gnu.org List" <bug-gnulib <at> gnu.org>
Cc: Jaroslav Škarvada <jskarvad <at> redhat.com>,
 Paul Eggert <eggert <at> cs.ucla.edu>, jackson <at> fastmail.fm, 77800 <at> debbugs.gnu.org
Subject: Re: bug#77800: grep-3.12: write-error-msg test failure on fedora
 rawhide (f43)
Date: Fri, 18 Apr 2025 11:40:17 +0100
On 18/04/2025 06:18, Jim Meyering wrote:
> On Tue, Apr 15, 2025 at 9:17 PM Jim Meyering <jim <at> meyering.net> wrote:
> ...
>> We're going to have to revise that code.
>> The difference I see is that before rawhide, that fclose would fail.
>> It's perfectly fine for fclose to succeed in this case, as now happens
>> on rawhide (because with 4k BUFSIZ, the fclose wrote nothing -- the
>> preceding 4096-byte write is what failed).
>>
>> Here's a better patch: (technically, we could factor it somewhat, but
>> readability would suffer disproportionately)
> 
> I didn't take the time to find a precise commit, but this bug predates
> the move from closeout.c to gnulib's close-stdout.c in 2006. As I
> write this, I'm installing Fedora 42.
> I'll probably push the attached to gnulib tomorrow:

The variance here seems to be due to stdio buffer size:

 $ for b in 0 4096 8192; do
     echo bs=$b
     for ws in 4095 4096 4097; do
       printf "ws=$ws: "
       stdbuf -o${b} printf %${ws}s >/dev/full
     done
   done

 bs=0
 ws=4095: printf: write error
 ws=4096: printf: write error
 ws=4097: printf: write error
 bs=4096
 ws=4095: printf: write error: No space left on device
 ws=4096: printf: write error
 ws=4097: printf: write error
 bs=8192
 ws=4095: printf: write error: No space left on device
 ws=4096: printf: write error: No space left on device
 ws=4097: printf: write error: No space left on device

I.e. write() always gives ENOSPC, it just whether it's called or not.
I.e. we get the more exact error if it's latent until we fflush() at exit.

$ for i in 4095 4096 4097; do ltrace -e fwrite -e fclose -e fflush -e ferror printf %${i}s >/dev/full; done
printf->fwrite("                                "..., 1, 4095, 0x7f15ca8225c0)                = 4095
printf->fflush(0x7f15ca8225c0)                                                                = -1
printf->fclose(0x7f15ca8225c0)                                                                = 0
printf: write error: No space left on device
+++ exited (status 1) +++
printf->fwrite("                                "..., 1, 4096, 0x7fb38377e5c0)                = 0
printf->ferror(0x7fb38377e5c0)                                                                = 1
printf->fflush(0x7fb38377e5c0)                                                                = 0
printf->fclose(0x7fb38377e5c0)                                                                = 0
printf: write error
+++ exited (status 1) +++
printf->fwrite("                                "..., 1, 4097, 0x7fd0372695c0)                = 0
printf->ferror(0x7fd0372695c0)                                                                = 1
printf->fflush(0x7fd0372695c0)                                                                = 0
printf->fclose(0x7fd0372695c0)                                                                = 0
printf: write error
+++ exited (status 1) +++

If a utility wants to give a more exact error it could operate like certain coreutils commands
and issue a specific error at fwrite (or other stdio function) call time.
Note one has to be careful to not output multiple errors in that case,
so it's not always appropriate to follow that course, but if appropriate
(to exit immediately) then ref the coreutils write_error() function:
https://github.com/coreutils/coreutils/blob/0d04b985/src/system.h#L750-L757

Now printf (vasnprintf) doesn't diagnose such write errors immediately,
so --help output may not be the route to ensure an ENOSPC error.
A hacky solution might be to change the test to use --version rather than --help,
to output a smaller amount of data, but that assumes the output is buffered.
It might be appropriate instead to just not look for the specific ENOSPC error.

cheers,
Pádraig




This bug report was last modified 7 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.