Subject: Re: bug#11424: coreutils: split tests hang on /dev/zero on GNU/Hurd

From: Jim Meyering <[email-masked]>
Date: Mon, 07 May 2012 09:46:43 +0200

Samuel Thibault wrote:
> Since some time, coreutils fails in split tests on GNU/Hurd. More
> precisely, these two:
>
> split/filter:55
> split --filter="head -c1 >/dev/null" -n 1 /dev/zero
>
> split/l-chunk:39
> split -n l/2 /dev/zero
>
> It seems that these two tests assume that split will stop by itself when
> given /dev/zero as input.  It does so on Linux, because /dev/zero there
> has stat_buf.st_size equal to 0, and thus split does just one loop, but
> on GNU/Hurd /dev/zero has stat_buf.st_size equal to LONG_MAX, and thus
> split just loops for a very long time.  Posix doesn't seem to talk much
> about what should be done here, but it seems to me that coreutils tests
> should not assume size being zero, and for instance use dd to fetch only
> the required bytes from /dev/zero.

Hi Samuel,
The real problem is that split was using stat.st_size from non-regular
files: that is not defined.

Here is a patch:

>From 0a63df4b669faf0585beab09f4b177c39d557b21 Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email-masked]>
Date: Mon, 7 May 2012 09:32:00 +0200
Subject: [PATCH] split: avoid apparent infloop when splitting /dev/zero w/-n
 on the Hurd

* src/split.c (main): Use stat.st_size only for regular files.
Samuel Thibault reported in http://bugs.gnu.org/11424 that the
/dev/zero-splitting tests would appear to infloop on GNU/Hurd,
because /dev/zero's st_size is LONG_MAX.  It was only a problem
when using the --number (-n) option.
* NEWS (Bug fixes): Mention it.
This bug was introduced with the --number option, via
commit v8.7-25-gbe10739
---
 NEWS        | 3 +++
 src/split.c | 4 +++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index fd563c0..7563646 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   was particularly easy to trigger, since there, the removal of D could
   precede the initial stat.  [This bug was present in "the beginning".]

+  split --number=C /dev/null no longer appears to infloop on GNU/Hurd
+  [bug introduced in coreutils-8.8]
+
 ** New features

   fmt now accepts the --goal=WIDTH (-g) option.
diff --git a/src/split.c b/src/split.c
index 99f6390..062aede 100644
--- a/src/split.c
+++ b/src/split.c
@@ -1339,7 +1339,9 @@ main (int argc, char **argv)
     error (EXIT_FAILURE, errno, "%s", infile);
   if (in_blk_size == 0)
     in_blk_size = io_blksize (stat_buf);
-  file_size = stat_buf.st_size;
+
+  /* stat.st_size is valid only for regular files.  For others, use 0.  */
+  file_size = S_ISREG (stat_buf.st_mode) ? stat_buf.st_size : 0;

   if (split_type == type_chunk_bytes || split_type == type_chunk_lines)
     {
--
1.7.10.1.457.g8275905