coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[coreutils] [PATCH] head: optionally indicate underrun of set limit


From: Stefan Tomanek
Subject: [coreutils] [PATCH] head: optionally indicate underrun of set limit
Date: Sun, 14 Nov 2010 17:07:42 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

It is often convinient to detect whether head has in fact printed the
requested number of lines or if EOF was reached before reaching that
point. This patch adds the option --indicate-underrun, which makes
"head" exit with a status of 4 instead of 0 if no more data could be
read from its input.

This ability is useful when using head to chop a piped data stream
into slices and process it further:

datagenerator | while true; do
        head --indicate-underrun --bytes 2G | processdatachunk
        # check exit status of head to abort the loop on EOF
done

An example might be the creation of a tar archive while uploading it to
a broken FTP server in chunks of less than 2GB.

Signed-off-by: Stefan Tomanek <address@hidden>
---
 src/head.c |   30 ++++++++++++++++++++++++++----
 1 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/head.c b/src/head.c
index dd3dc89..5d6b970 100644
--- a/src/head.c
+++ b/src/head.c
@@ -49,6 +49,11 @@
 /* Number of lines/chars/blocks to head. */
 #define DEFAULT_NUMBER 10
 
+/* Exit code to return if EOF is hit before reaching the preset limit */
+#define EXIT_LIMIT_UNDERRUN 4
+#define xstr(s) str(s)
+#define str(s) #s
+
 /* Useful only when eliding tail bytes or lines.
    If true, skip the is-regular-file test used to determine whether
    to use the lseek optimization.  Instead, use the more general (and
@@ -67,6 +72,11 @@ enum header_mode
 /* Have we ever read standard input?  */
 static bool have_read_stdin;
 
+/* did we reach EOF while reading? */
+static bool have_reached_eof;
+/* do we wish to indicate this via exit code? */
+static bool indicate_underrun;
+
 enum Copy_fd_status
   {
     COPY_FD_OK = 0,
@@ -91,6 +101,7 @@ static struct option const long_options[] =
   {"quiet", no_argument, NULL, 'q'},
   {"silent", no_argument, NULL, 'q'},
   {"verbose", no_argument, NULL, 'v'},
+  {"indicate-eof", no_argument, NULL, 'e'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -99,7 +110,7 @@ static struct option const long_options[] =
 void
 usage (int status)
 {
-  if (status != EXIT_SUCCESS)
+  if (status != EXIT_SUCCESS || status != EXIT_LIMIT_UNDERRUN)
     fprintf (stderr, _("Try `%s --help' for more information.\n"),
              program_name);
   else
@@ -128,6 +139,8 @@ Mandatory arguments to long options are mandatory for short 
options too.\n\
       fputs (_("\
   -q, --quiet, --silent    never print headers giving file names\n\
   -v, --verbose            always print headers giving file names\n\
+      --indicate-underrun  change exit code to " xstr(EXIT_LIMIT_UNDERRUN) " 
if EOF is reached before\n\
+                             hitting the set limit\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -752,8 +765,10 @@ head_bytes (const char *filename, int fd, uintmax_t 
bytes_to_write)
           error (0, errno, _("error reading %s"), quote (filename));
           return false;
         }
-      if (bytes_read == 0)
+      if (bytes_read == 0) {
+        have_reached_eof = true;
         break;
+      }
       if (fwrite (buffer, 1, bytes_read, stdout) < bytes_read)
         error (EXIT_FAILURE, errno, _("write error"));
       bytes_to_write -= bytes_read;
@@ -776,8 +791,11 @@ head_lines (const char *filename, int fd, uintmax_t 
lines_to_write)
           error (0, errno, _("error reading %s"), quote (filename));
           return false;
         }
-      if (bytes_read == 0)
+      if (bytes_read == 0) {
+        /* FIXME we have to check whether we read sufficient lines already */
+        have_reached_eof = true;
         break;
+      }
       while (bytes_to_write < bytes_read)
         if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
           {
@@ -1025,6 +1043,10 @@ main (int argc, char **argv)
           header_mode = always;
           break;
 
+       case 'e':
+          indicate_underrun = true;
+          break;
+
         case_GETOPT_HELP_CHAR;
 
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -1060,5 +1082,5 @@ main (int argc, char **argv)
   if (have_read_stdin && close (STDIN_FILENO) < 0)
     error (EXIT_FAILURE, errno, "-");
 
-  exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+  exit (ok ? ( (have_reached_eof && indicate_underrun) ? EXIT_LIMIT_UNDERRUN : 
EXIT_SUCCESS ) : EXIT_FAILURE);
 }
-- 
1.7.2.3



reply via email to

[Prev in Thread] Current Thread [Next in Thread]