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) {