On 03/11/2025 06:36, Collin Funk wrote:
This improvement is due to changes to Gnulib's fprintftime module.

* NEWS: Mention the improvement.
* tests/misc/write-errors.sh: Add a date invocation.
---
  NEWS                       | 4 ++--
  tests/misc/write-errors.sh | 1 +
  2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 2802c0c7b..3e20b8bb9 100644
--- a/NEWS
+++ b/NEWS
@@ -65,8 +65,8 @@ GNU coreutils NEWS                                    -*- 
outline -*-
** Improvements - 'fmt', 'nl', and 'pr' will now exit promptly upon receiving a write error,
-  which is significant when reading large / unbounded inputs.
+  'fmt', 'date', 'nl', and 'pr' will now exit promptly upon receiving a write
+  error, which is significant when reading large / unbounded inputs.
install, sort, and split now use posix_spawn() to invoke child programs more
    efficiently and more independently from their own memory usage.
diff --git a/tests/misc/write-errors.sh b/tests/misc/write-errors.sh
index b33e84a3d..60496fc06 100755
--- a/tests/misc/write-errors.sh
+++ b/tests/misc/write-errors.sh
@@ -30,6 +30,7 @@ cat /dev/zero
  comm -z /dev/zero /dev/zero
  cut -z -c1- /dev/zero
  cut -z -f1- /dev/zero
+date +%2147483648c
  dd if=/dev/zero
  expand /dev/zero
  factor --version; yes 1 | factor

Cool.

Why pick 2^31 BTW ? Wouldn't 2^31-1 (i.e. INT_MAX) suffice?
In either case it's probably better to use getlimits and $INT_MAX (or 
$INT_OFLOW if needed).
Specific numbers like this sets off all sorts of questions in my head.

BTW it's interesting that date supports $INT_OFLOW, while printf does not:

  $ src/date '+%2147483648c' >/dev/full; echo $?
  date: fprintftime: No space left on device
  date: write error: No space left on device
  1

  $ time src/printf '%2147483648s' ''; echo $?
  printf: write error
  real  0m0.003s
  1

  $ time printf '%2147483648s' ''; echo $?
  real  0m0.000s
  0

Note above shows that bash printf does not diagnose the issue
which looks like a bug, while our external printf does.
However bash printf is better in that it promptly
diagnoses an output error, while the external printf does not:

  $ time printf '%2147483647s' '' '' '' '' '' '' '' >/dev/full; echo $?
  bash: printf: write error: No space left on device
  real  0m0.000s
  1

  $ time src/printf '%2147483647s' '' '' '' '' '' '' '' '' ''  >/dev/full; echo 
$?
  printf: write error
  real  0m10.282s
  1

Not a huge issue, but I might look into it.

I've pushed 3 other patches related to date errors (attached):

1. get date(1) to exit promptly if processing lots of dates with --file
2. translate/clarify the "fprintftime" diagnostic shown above
3. avoid the double diagnostic with "fprintftime" above.

thanks!
Padraig
From 7d17e1d36c4f0df71e9ff8d0a20a07f9c35bbb61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Mon, 3 Nov 2025 12:44:07 +0000
Subject: [PATCH 1/3] date: promptly diagnose write errors with --file

* src/date.c (batch_convert): Check error state of stdout
after each date is processed.
* tests/misc/write-errors.sh: Add a test case.
---
 src/date.c                 | 3 +++
 tests/misc/write-errors.sh | 1 +
 2 files changed, 4 insertions(+)

diff --git a/src/date.c b/src/date.c
index db16f3225..91651e794 100644
--- a/src/date.c
+++ b/src/date.c
@@ -448,6 +448,9 @@ batch_convert (char const *input_filename,
         {
           ok &= show_date_helper (format, format_in_c_locale, when, tz);
         }
+
+      if (ferror (stdout))
+        write_error ();
     }
 
   if (fclose (in_stream) == EOF)
diff --git a/tests/misc/write-errors.sh b/tests/misc/write-errors.sh
index b33e84a3d..612658c6a 100755
--- a/tests/misc/write-errors.sh
+++ b/tests/misc/write-errors.sh
@@ -30,6 +30,7 @@ cat /dev/zero
 comm -z /dev/zero /dev/zero
 cut -z -c1- /dev/zero
 cut -z -f1- /dev/zero
+date --version; yes 0 | date -f-
 dd if=/dev/zero
 expand /dev/zero
 factor --version; yes 1 | factor
-- 
2.51.0

From d870bfbca128dd8a8a23f0e3d97e3c85f7eee552 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Mon, 3 Nov 2025 12:55:35 +0000
Subject: [PATCH 2/3] date: translate/clarify recent error message

* src/show-date.c (show_date): Flagged by syntax-check.
---
 src/show-date.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/show-date.c b/src/show-date.c
index 59d5cf936..96cefc810 100644
--- a/src/show-date.c
+++ b/src/show-date.c
@@ -31,7 +31,7 @@ show_date (char const *format, struct timespec when, timezone_t tz)
 
   if (fprintftime (stdout, format, &tm, tz, when.tv_nsec) < 0)
     {
-      error (0, errno, "fprintftime");
+      error (0, errno, _("fprintftime error"));
       return false;
     }
 
-- 
2.51.0

From cb0ab4ef394c37c4f874f150db7f75f3ba617dd4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Mon, 3 Nov 2025 13:00:32 +0000
Subject: [PATCH 3/3] date: avoid a duplicated write error diagnotic

* src/show-date.c (show_date): Only show the fprintftime() diagnostic
if a further diagnostic will not be shown.
---
 src/show-date.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/show-date.c b/src/show-date.c
index 96cefc810..ff1470e8e 100644
--- a/src/show-date.c
+++ b/src/show-date.c
@@ -31,7 +31,8 @@ show_date (char const *format, struct timespec when, timezone_t tz)
 
   if (fprintftime (stdout, format, &tm, tz, when.tv_nsec) < 0)
     {
-      error (0, errno, _("fprintftime error"));
+      if (! ferror (stdout))  /* otherwise it will be diagnosed later.  */
+        error (0, errno, _("fprintftime error"));
       return false;
     }
 
-- 
2.51.0

Reply via email to