tail patch - allows fractional seconds with -s

Matt Rickard <[email protected]> Mon, 9 Dec 2002 02:37:04 -0500
Newsgroups gmane.comp.gnu.textutils.bugs
Message-ID <[email protected]>
I have modified the GNU textutils tail.c to allow for fractional seconds
with the -s option.  e.g. "tail -f -s 1.325 filename", rather than only
whole number, as per the FIXME in the current tail.c code.  The diff
follows.

Matt Rickard

--- tail.c.old	2002-07-29 04:40:21.000000000 -0400
+++ tail.c	2002-12-09 02:21:30.000000000 -0500
@@ -21,7 +21,8 @@
 
    Original version by Paul Rubin <[email protected]>.
    Extensions by David MacKenzie <[email protected]>.
-   tail -f for multiple files by Ian Lance Taylor <[email protected]>.  */
+   tail -f for multiple files by Ian Lance Taylor <[email protected]>. 
+   Allowing fractional seconds for -s by Matt Rickard <[email protected]>. */
 
 #include <config.h>
 
@@ -66,6 +67,9 @@
 /* FIXME: make Follow_name the default?  */
 #define DEFAULT_FOLLOW_MODE Follow_descriptor
 
+/* Seconds to microseconds conversion factor (10^6) */
+#define SECONDS_TO_MICROSECONDS 1000000
+
 enum Follow_mode
 {
   /* Follow the name of each file: if the file is renamed, try to reopen
@@ -177,11 +181,10 @@
 /* The name this program was run with.  */
 char *program_name;
 
-/* The number of seconds to sleep between iterations.
+/* The number of microseconds to sleep between iterations.
    During one iteration, every file name or descriptor is checked to
    see if it has changed.  */
-/* FIXME: allow fractional seconds */
-static unsigned int sleep_interval = 1;
+static unsigned long sleep_interval = 1000000;
 
 /* The process ID of the process (presumably on the current host)
    that is writing to all followed files.  */
@@ -276,7 +279,7 @@
       --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, each iteration lasts approximately S\n\
-                           (default 1) seconds\n\
+                           (default 1.0) seconds\n\
   -v, --verbose            always output headers giving file names\n\
 "), stdout);
      fputs (HELP_OPTION_DESCRIPTION, stdout);
@@ -1022,7 +1025,7 @@
 	{
 	  if (writer_is_dead)
 	    break;
-	  sleep (sleep_interval);
+	  usleep(sleep_interval);
 
 	  /* Once the writer is dead, read the files once more to
 	     avoid a race condition.  */
@@ -1536,15 +1539,28 @@
 
 	case 's':
 	  {
-	    strtol_error s_err;
-	    unsigned long int tmp_ulong;
-	    s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, "");
-	    if (s_err != LONGINT_OK || tmp_ulong > UINT_MAX)
-	      {
-		error (EXIT_FAILURE, 0,
-		       _("%s: invalid number of seconds"), optarg);
-	      }
-	    sleep_interval = tmp_ulong;
+	    double tmp_double, other_tmp_double;
+	    char *endp;
+	    tmp_double = strtod(optarg, &endp);
+	    if(endp > optarg) /* valid double */
+	    {
+	       other_tmp_double = tmp_double * SECONDS_TO_MICROSECONDS;
+	       if(other_tmp_double <= (double)ULONG_MAX) /* valid
+			 			      unsigned long) */
+	       {
+	          sleep_interval = other_tmp_double;
+	       }
+	       else
+	       {
+	          error (EXIT_FAILURE, 0, 
+	            _("%s: invalid number of seconds"), optarg);   
+	       }
+	    }
+	    else
+	    {
+	       error (EXIT_FAILURE, 0,
+	         _("%s: invalid number of seconds"), optarg);
+	    }
 	  }
 	  break;