On Sun, Dec 04, 2016 at 09:55:07PM -0800, Michael Forney wrote:
> The FILE streams are buffered, so the end result is essentially the
> same, except now lines are printed as they are read since we don't wait
> until the entire buffer is filled.
> 
> This also fixes an issue where only part of the lines during the follow
> were printed if they contained NUL bytes.
> ---
>  tail.c | 22 +++++++++++++---------
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/tail.c b/tail.c
> index 711707f..ad97308 100644
> --- a/tail.c
> +++ b/tail.c
> @@ -20,6 +20,7 @@ dropinit(FILE *fp, const char *str, size_t n)
>       char *buf = NULL;
>       size_t size = 0, i = 1;
>       ssize_t len;
> +     int c;
>  
>       if (mode == 'n') {
>               while (i < n && (len = getline(&buf, &size, fp)) > 0)
> @@ -30,7 +31,10 @@ dropinit(FILE *fp, const char *str, size_t n)
>                       i++;
>       }
>       free(buf);
> -     concat(fp, str, stdout, "<stdout>");
> +     while ((c = fgetc(fp)) != EOF) {
> +             if (fputc(c, stdout) == EOF)
> +                     break;
> +     }
>  }
>  
>  static void
> @@ -88,9 +92,9 @@ main(int argc, char *argv[])
>  {
>       struct stat st1, st2;
>       FILE *fp;
> -     size_t tmpsize, n = 10;
> -     int fflag = 0, ret = 0, newline = 0, many = 0;
> -     char *numstr, *tmp;
> +     size_t n = 10;
> +     int fflag = 0, ret = 0, newline = 0, many = 0, c;
> +     char *numstr;
>       void (*tail)(FILE *, const char *, size_t) = taketail;
>  
>       ARGBEGIN {
> @@ -141,13 +145,13 @@ main(int argc, char *argv[])
>                                       ret = 1;
>                               continue;
>                       }
> -                     for (tmp = NULL, tmpsize = 0;;) {
> -                             while (getline(&tmp, &tmpsize, fp) > 0) {
> -                                     fputs(tmp, stdout);
> -                                     fflush(stdout);
> +                     for (;;) {
> +                             while ((c = fgetc(fp)) != EOF) {
> +                                     if (fputc(c, stdout) == EOF)
> +                                             eprintf("fputc <stdout>:");
>                               }
>                               if (ferror(fp))
> -                                     eprintf("readline %s:", *argv);
> +                                     eprintf("fgetc %s:", *argv);
>                               clearerr(fp);
>                               /* ignore error in case file was removed, we 
> continue
>                                * tracking the existing open file descriptor */
> -- 
> 2.11.0
> 
> 

Hey Michael,

Just wondering: did you test if this will be much slower? Ideally test with
both musl and glibc.

-- 
Kind regards,
Hiltjo

Reply via email to