On Mon, Jun 16, 2014 at 10:57 PM, Ted Unangst <[email protected]> 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];
        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);
+       if (evcount == -1) {
+               close(nfd);
+               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) {
+                                       shutdown(nfd, SHUT_RD);
                                        return;
+                               } 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)
{
+                                                               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;
+                                               }
+                                       }
+                               }

-- 
---------------------------------------------------------------------------------------------------------------------
() ascii ribbon campaign - against html e-mail
/\

Reply via email to