bug-coreutils
[Top][All Lists]
Advanced

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

Re: [patch #6532] tail -u -- unbuffered output


From: Jim Meyering
Subject: Re: [patch #6532] tail -u -- unbuffered output
Date: Tue, 03 Jun 2008 18:08:26 +0200

Juergen Weigert <address@hidden> wrote:
> when tail's stdout is not a terminal, stdio library fools us by buffering
> large chunks of data.
> This patch adds an option to run in unbuffered mode,
> Implemented as straightforward use of fflush().
>
> Date: Tuesday 06/03/2008 at 15:14  Name: tail-unbuffered.diff  Size: 3kB
> By: jnweiger
> patch against coreutils-6.11 as found in SUSE Linux 11.0
> <http://savannah.gnu.org/patch/download.php?file_id=15788>

Hi Juergen,

Thank you for the patch!
Please follow the guidelines in HACKING when sending future patches:

  coreutils' contribution/style guidelines
    http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=blob;f=HACKING;hb=HEAD


Here's a revised version of the patch (written by you?).
Changes include:
  - omit the short-name -u option
  - AFAICS, --unbuffered is useful only with --follow, so...
  - warn if --unbuffered is used without --follow
  - don't initialize "unbuffered" in main
  - report fflush failure on the spot
  - improve fwrite test (not related to your change -- just in the vicinity)

Items remaining:
  - a NEWS entry
  - texinfo documentation patch describing the option
      and saying how and when it is useful
  - a complete ChangeLog-style log entry
  - a test

None of that is a big deal, but it adds up if I take
time to do it for every patch that's accepted.

If you'd like to finish up, that'd be great.

>From 866896ce6be3b5d18b45b607a932549f4576fdf0 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 3 Jun 2008 17:51:21 +0200
Subject: [PATCH] tail: new option: --unbuffered

* src/tail.c (usage): FIXME
---
 src/tail.c |   27 ++++++++++++++++++++++++---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/tail.c b/src/tail.c
index 1ce207e..2ba2b0a 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -144,6 +144,10 @@ static bool forever;
 /* If true, count from start of file instead of end.  */
 static bool from_start;

+/* If true, call fflush after each frwite to stdout.
+   Enabled only when used with --follow (-f).  */
+static bool unbuffered;
+
 /* If true, print filename headers.  */
 static bool print_headers;

@@ -182,7 +186,8 @@ enum
   MAX_UNCHANGED_STATS_OPTION,
   PID_OPTION,
   PRESUME_INPUT_PIPE_OPTION,
-  LONG_FOLLOW_OPTION
+  LONG_FOLLOW_OPTION,
+  UNBUFFERED_OPTION
 };

 static struct option const long_options[] =
@@ -198,6 +203,7 @@ static struct option const long_options[] =
   {"retry", no_argument, NULL, RETRY_OPTION},
   {"silent", no_argument, NULL, 'q'},
   {"sleep-interval", required_argument, NULL, 's'},
+  {"unbuffered", no_argument, NULL, UNBUFFERED_OPTION},
   {"verbose", no_argument, NULL, 'v'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
@@ -256,7 +262,8 @@ Mandatory arguments to long options are mandatory for short 
options too.\n\
       --pid=PID            with -f, terminate after process ID, PID dies\n\
   -q, --quiet, --silent    never output headers giving file names\n\
   -s, --sleep-interval=S   with -f, sleep for approximately S seconds\n\
-                           (default 1.0) between iterations.\n\
+                           (default 1.0) between iterations\n\
+      --unbuffered         with -f, do not buffer output\n\
   -v, --verbose            always output headers giving file names\n\
 "), stdout);
      fputs (HELP_OPTION_DESCRIPTION, stdout);
@@ -303,7 +310,11 @@ pretty_name (struct File_spec const *f)
 static void
 xwrite_stdout (char const *buffer, size_t n_bytes)
 {
-  if (n_bytes > 0 && fwrite (buffer, 1, n_bytes, stdout) == 0)
+  if (n_bytes == 0)
+    return;
+
+  if (fwrite (buffer, n_bytes, 1, stdout) != 1
+      || (unbuffered && fflush (stdout) != 0))
     error (EXIT_FAILURE, errno, _("write error"));
 }

@@ -1544,6 +1555,10 @@ parse_options (int argc, char **argv,
          }
          break;

+       case UNBUFFERED_OPTION:
+         unbuffered = true;
+         break;
+
        case 'v':
          *header_mode = always;
          break;
@@ -1573,6 +1588,12 @@ parse_options (int argc, char **argv,
       error (0, 0, _("warning: --pid=PID is not supported on this system"));
       pid = 0;
     }
+
+  if (unbuffered && !forever)
+    {
+      error (0, 0, _("warning: --unbuffered is useful only when following"));
+      unbuffered = false;
+    }
 }

 int
--
1.5.6.rc1.2.g5648b




reply via email to

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