On 07/03/15 12:10, Pádraig Brady wrote:
> BTW I noticed tee uses stdio calls which is redundant overhead currently.
> It wouldn't if we added a --buffered call to tee so that it might
> honor stdbuf(1), though I'm not sure it's worth that flexibility in tee.

I've attached this change, though I'm 50:50 about applying it,
since it's only a micro optimization.

cheers,
Pádraig.
>From f5d31e13265fda65017145f9206d634d6715cded Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Mon, 9 Mar 2015 23:58:25 +0000
Subject: [PATCH] tee: avoid using stdio as tee doesn't buffer

* src/tee.c (tee_files): Since tee doesn't buffer, avoid using
stdio streams and just the lower level fd interface.
Since we'd disabled buffering in stdio, this is
not a significant optimization.
---
 src/tee.c | 37 ++++++++++++++++---------------------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/src/tee.c b/src/tee.c
index 3c39a4a..a0ed3c2 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -25,7 +25,7 @@
 #include "argmatch.h"
 #include "error.h"
 #include "fadvise.h"
-#include "stdio--.h"
+#include "full-write.h"
 #include "xfreopen.h"
 
 /* The official name of this program (e.g., no 'g' prefix).  */
@@ -182,15 +182,16 @@ static bool
 tee_files (int nfiles, const char **files)
 {
   size_t n_outputs = 0;
-  FILE **descriptors;
+  int *descriptors;
   char buffer[BUFSIZ];
   ssize_t bytes_read = 0;
   int i;
   bool ok = true;
-  char const *mode_string =
-    (O_BINARY
-     ? (append ? "ab" : "wb")
-     : (append ? "a" : "w"));
+  int mode = O_WRONLY | O_CREAT | O_BINARY;
+  if (append)
+    mode |= O_APPEND;
+  else
+    mode |= O_TRUNC;
 
   descriptors = xnmalloc (nfiles + 1, sizeof *descriptors);
 
@@ -208,16 +209,15 @@ tee_files (int nfiles, const char **files)
 
   /* In the array of NFILES + 1 descriptors, make
      the first one correspond to standard output.   */
-  descriptors[0] = stdout;
+  descriptors[0] = STDOUT_FILENO;
   files[0] = _("standard output");
-  setvbuf (stdout, NULL, _IONBF, 0);
   n_outputs++;
 
   for (i = 1; i <= nfiles; i++)
     {
       /* Do not treat "-" specially - as mandated by POSIX.  */
-      descriptors[i] = fopen (files[i], mode_string);
-      if (descriptors[i] == NULL)
+      descriptors[i] = open (files[i], mode, 0666);
+      if (descriptors[i] == -1)
         {
           error (output_error == output_error_exit
                  || output_error == output_error_exit_nopipe,
@@ -225,15 +225,12 @@ tee_files (int nfiles, const char **files)
           ok = false;
         }
       else
-        {
-          setvbuf (descriptors[i], NULL, _IONBF, 0);
-          n_outputs++;
-        }
+        n_outputs++;
     }
 
   while (n_outputs)
     {
-      bytes_read = read (0, buffer, sizeof buffer);
+      bytes_read = read (STDIN_FILENO, buffer, sizeof buffer);
       if (bytes_read < 0 && errno == EINTR)
         continue;
       if (bytes_read <= 0)
@@ -242,21 +239,19 @@ tee_files (int nfiles, const char **files)
       /* Write to all NFILES + 1 descriptors.
          Standard output is the first one.  */
       for (i = 0; i <= nfiles; i++)
-        if (descriptors[i]
-            && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
+        if (descriptors[i] != -1
+            && full_write (descriptors[i], buffer, bytes_read) != bytes_read)
           {
             int w_errno = errno;
             bool fail = errno != EPIPE || (output_error == output_error_exit
                                           || output_error == output_error_warn);
-            if (descriptors[i] == stdout)
-              clearerr (stdout); /* Avoid redundant close_stdout diagnostic.  */
             if (fail)
               {
                 error (output_error == output_error_exit
                        || output_error == output_error_exit_nopipe,
                        w_errno, "%s", files[i]);
               }
-            descriptors[i] = NULL;
+            descriptors[i] = -1;
             if (fail)
               ok = false;
             n_outputs--;
@@ -271,7 +266,7 @@ tee_files (int nfiles, const char **files)
 
   /* Close the files, but not standard output.  */
   for (i = 1; i <= nfiles; i++)
-    if (descriptors[i] && fclose (descriptors[i]) != 0)
+    if (descriptors[i] != -1 && close (descriptors[i]) != 0)
       {
         error (0, errno, "%s", files[i]);
         ok = false;
-- 
2.1.0

Reply via email to