On Sun, Jun 22, 2014 at 9:20 AM, John-Mark Gurney <j...@funkthat.com> wrote:
> sven falempin wrote this message on Tue, Jun 17, 2014 at 07:42 -0400: > > On Mon, Jun 16, 2014 at 10:57 PM, Ted Unangst <t...@tedunangst.com> > wrote: > > > > > On Sat, Jun 14, 2014 at 10:55, Ted Unangst wrote: > > > > On Fri, Jun 13, 2014 at 10:40, sven falempin wrote: > > > >>>> > > > >>>> Now soliciting diffs to change readwrite to a loop with two > buffers > > > >>>> that poll()s in all four directions. :) > > > >>>> > > > >>>> > > > >>> Is using kqueue ok ? > > > >>> > > > >>> like : http://pastebin.com/F1c5Hswi > > > > > > > > uh, maybe. the kqueue changes make it harder to review at first, but > > > > I'll look closer soonish. > > > > > > Turns out pastebin isn't a very good place for storing diffs. It's > > > gone now, making it very hard to review. Can you send the diff to the > > > list? Thanks. > > > > > > > > > Index: netcat.c > > =================================================================== > > RCS file: /cvs/src/usr.bin/nc/netcat.c,v > > retrieving revision 1.121 > > diff -u -p -r1.121 netcat.c > > --- netcat.c 10 Jun 2014 16:35:42 -0000 1.121 > > +++ netcat.c 14 Jun 2014 17:46:31 -0000 > > @@ -36,6 +36,7 @@ > > #include <sys/time.h> > > #include <sys/uio.h> > > #include <sys/un.h> > > +#include <sys/event.h> > > > > #include <netinet/in.h> > > #include <netinet/in_systm.h> > > @@ -734,58 +735,124 @@ readwrite(int nfd) > > { > > struct pollfd pfd[2]; > > pfd can be removed, I don't think you're using it... > > > unsigned char buf[16 * 1024]; > > + struct kevent keventlist[4]; > > + quad_t write_space_network; > > + quad_t write_space_stdout; > > + quad_t available; > > int n, wfd = fileno(stdin); > > int lfd = fileno(stdout); > > int plen; > > + int kq; > > + int evcount; > > + int evid; > > > > plen = sizeof(buf); > > > > - /* Setup Network FD */ > > - pfd[0].fd = nfd; > > - pfd[0].events = POLLIN; > > + /* Set up kqueue*/ > > + kq = kqueue(); > > + if (kq == -1) { > > + close(nfd); > > + err(1, "Kqueue Error"); > > + } > > + > > + /* Set up STDOUT FD. */ > > + EV_SET(&keventlist[0], nfd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); > > + > > + /* Set up Network FD */ > > + EV_SET(&keventlist[1], lfd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); > > + EV_SET(&keventlist[2], nfd, EVFILT_READ, EV_ADD, 0, 0, NULL); > > > > /* Set up STDIN FD. */ > > - pfd[1].fd = wfd; > > - pfd[1].events = POLLIN; > > + EV_SET(&keventlist[3], wfd, EVFILT_READ, EV_ADD, 0, 0, NULL); > > > > - while (pfd[0].fd != -1) { > > + /* Registering events */ > > + evcount = kevent(kq, keventlist, 4, NULL, 0, NULL); > > You should pass the keventlist in to see if any erros happened while > registering.. it'd be bad if there was, but we did tell the user that > IO isn't going to happen... > > > + if (evcount == -1) { > > + close(nfd); > > We should probably close kq here... All the places later in the > function that close nfd, should close kq... > > > + err(1, "Kevent Error"); > > + } > > + > > + while (evcount != -1) { > > if (iflag) > > sleep(iflag); > > - > > - if ((n = poll(pfd, 2 - dflag, timeout)) < 0) { > > + evcount = kevent(kq, NULL, 0, keventlist, 4, NULL); > > + if (evcount == -1) { > > close(nfd); > > - err(1, "Polling Error"); > > + err(1, "Kevent Error"); > > } > > + for (evid = 0; evid < evcount; evid++) { > > + struct kevent event = keventlist[evid]; > > + if (event.flags & EV_ERROR) { > > + close(nfd); > > + err(1, "Kevent Error"); > > + } > > > > - if (n == 0) > > - return; > > - > > - if (pfd[0].revents & POLLIN) { > > - if ((n = read(nfd, buf, plen)) < 0) > > - return; > > - else if (n == 0) { > > - shutdown(nfd, SHUT_RD); > > - pfd[0].fd = -1; > > - pfd[0].events = 0; > > - } else { > > - if (tflag) > > - atelnet(nfd, buf, n); > > - if (atomicio(vwrite, lfd, buf, n) != n) > > + if (event.ident == nfd) { > > + if (event.flags & EV_EOF) { > > You (at least on FreeBSD) can have data along w/ the EOF flag: > It is > possible for EOF to be returned (indicating the con- > nection is gone) while there is still data pending > in the socket buffer. > > So, you should check for data first.. > > Also, you don't check which direction got the EOF, so you might be > shutting down the wrong direction.. > > > + shutdown(nfd, SHUT_RD); > > return; > > Are you sure you want to return here? What if there is more data in > the other direction? > > > + } else { > > + if (event.filter == > EVFILT_WRITE) { > > + write_space_network = > > event.data; > > + } > > + else if (event.filter == > > EVFILT_READ) { > > + available = > MIN(event.data, > > write_space_stdout); > > + available = > MIN(available, > > plen); > > + if (available > 0) { > > + n = read(nfd, > buf, > > available); > > + if (n != > available) > > { > > You should probably raise this as an error like the other cases... > > > + return; > > + } else { > > + n = > > write(lfd, buf, available); > > + if (n != > > available) { > > + > > return; > > + } > > + } > > + > write_space_stdout > > -= available; > > + /* Break to > ignore > > EVFILT_WRITE that could > > + * be in current > > keventlist, after this event > > + * and which is > now > > invalid, because we just > > + * write in the > fd. > > + */ > > + break; > > + } > > + } > > + } > > } > > - } > > - > > - if (!dflag && pfd[1].revents & POLLIN) { > > - if ((n = read(wfd, buf, plen)) < 0) > > - return; > > - else if (n == 0) { > > - if (Nflag) > > - shutdown(nfd, SHUT_WR); > > - pfd[1].fd = -1; > > - pfd[1].events = 0; > > - } else { > > - if (atomicio(vwrite, nfd, buf, n) != n) > > + else if (event.ident == lfd) { > > + if (event.filter == EVFILT_WRITE) { > > + write_space_stdout = event.data; > > + } > > + } > > + else if (event.ident == wfd) { > > + if (event.flags & EV_EOF) { > > + if (Nflag) > > + shutdown(nfd, SHUT_WR); > > return; > > + } else { > > + if (event.filter == EVFILT_READ) > { > > + available = > MIN(event.data, > > write_space_network); > > + available = > MIN(available, > > plen); > > + if (available > 0) { > > + n = read(wfd, > buf, > > available); > > + if (n != > available) > > { > > + return; > > + } else { > > + n = > > write(nfd, buf, available); > > + if (n != > > available) { > > + > > return; > > + } > > + } > > + > write_space_network > > -= available; > > + /* Break to > ignore > > EVFILT_WRITE that could > > + * be in current > > keventlist, after this event > > + * and which is > now > > invalid, because we just > > + * write in the > fd. > > + */ > > + break; > > + } > > + } > > + } > > As this second half of the path is the same as the first, my previous > comments also apply... > > -- > John-Mark Gurney Voice: +1 415 225 5579 > > "All that I will do, has been done, All that I have, has not." > Thank you for the review :-) -- --------------------------------------------------------------------------------------------------------------------- () ascii ribbon campaign - against html e-mail /\