On Sat, Nov 20, 2021 at 02:22:41PM -0700, Todd C. Miller wrote:
> On Sat, 20 Nov 2021 11:19:13 -0600, Scott Cheloha wrote:
> 
> > > One advantage to using stdio is that
> > > it will use the optimal I/O blocksize automatically so you could
> > > try using that instead of write(2) and see how it performs.
> >
> > tee(1) needs to write input to N drains, N >= 1.  If we use stdio that
> > means we're doing N additional userspace copies, no?
> 
> Yes, that is true.  Right now tee(1) doesn't check for partial
> writes which I suppose might happen with a larger buffer.  In
> practice, as long as it is less than MAXPHYS it should be OK.

This code in the inner loop doesn't handle partial writes?

   114                  SLIST_FOREACH(p, &head, next) {
   115                          n = rval;
   116                          bp = buf;
   117                          do {
   118                                  if ((wval = write(p->fd, bp, n)) == -1) 
{
   119                                          warn("%s", p->name);
   120                                          exitval = 1;
   121                                          break;
   122                                  }
   123                                  bp += wval;
   124                          } while (n -= wval);
   125                  }

It's not the idiomatic loop from the manpage, but near as I can tell
it is equivalent.

... should we make it idiomatic?  Saves a few lines, is less
confusing, etc.

Index: tee.c
===================================================================
RCS file: /cvs/src/usr.bin/tee/tee.c,v
retrieving revision 1.12
diff -u -p -r1.12 tee.c
--- tee.c       11 Jul 2017 13:14:59 -0000      1.12
+++ tee.c       21 Nov 2021 02:16:09 -0000
@@ -68,7 +68,6 @@ main(int argc, char *argv[])
        struct list *p;
        int fd;
        ssize_t n, rval, wval;
-       char *bp;
        int append, ch, exitval;
        char buf[8192];
 
@@ -112,16 +111,14 @@ main(int argc, char *argv[])
 
        while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
                SLIST_FOREACH(p, &head, next) {
-                       n = rval;
-                       bp = buf;
-                       do {
-                               if ((wval = write(p->fd, bp, n)) == -1) {
+                       for (n = 0; n < rval; n += wval) {
+                               wval = write(p->fd, buf + n, rval - n);
+                               if (wval == -1) {
                                        warn("%s", p->name);
                                        exitval = 1;
                                        break;
                                }
-                               bp += wval;
-                       } while (n -= wval);
+                       }
                }
        }
        if (rval == -1) {

Reply via email to