]> The Tcpdump Group git mirrors - libpcap/commitdiff
Merge pull request #1113 from fenner/no-eventfd
authorGuy Harris <[email protected]>
Thu, 25 Aug 2022 18:25:09 +0000 (11:25 -0700)
committerGitHub <[email protected]>
Thu, 25 Aug 2022 18:25:09 +0000 (11:25 -0700)
Close the eventfd if we are non-blocking

1  2 
pcap-linux.c
testprogs/Makefile.in

diff --combined pcap-linux.c
index 8ceffde1f3b234d8c663d89e11c4da41b6cb40f7,42ad9249d64030fa31c16c02029789c4816acf1e..43d2a9f0eec640865db9c841aa6d01f31c9fbce5
@@@ -842,7 -842,10 +842,10 @@@ static void      pcap_cleanup_linux( pcap_t 
                handlep->device = NULL;
        }
  
-       close(handlep->poll_breakloop_fd);
+       if (handlep->poll_breakloop_fd != -1) {
+               close(handlep->poll_breakloop_fd);
+               handlep->poll_breakloop_fd = -1;
+       }
        pcap_cleanup_live_common(handle);
  }
  
@@@ -941,7 -944,8 +944,8 @@@ static void pcap_breakloop_linux(pcap_
  
        uint64_t value = 1;
        /* XXX - what if this fails? */
-       (void)write(handlep->poll_breakloop_fd, &value, sizeof(value));
+       if (handlep->poll_breakloop_fd != -1)
+               (void)write(handlep->poll_breakloop_fd, &value, sizeof(value));
  }
  
  /*
@@@ -1485,7 -1489,7 +1489,7 @@@ get_if_ioctl_socket(void
         * capture on them, "why do no interfaces show up?" - when the
         * real problem is a permissions problem.  Error reports of that
         * type require a lot more back-and-forth to debug, as evidenced
 -       * by many Wireshark bugs/mailing list questions/Q&A questoins.)
 +       * by many Wireshark bugs/mailing list questions/Q&A questions.)
         *
         * So:
         *
@@@ -3375,7 -3379,23 +3379,23 @@@ pcap_setnonblock_linux(pcap_t *handle, 
                         */
                        handlep->timeout = ~handlep->timeout;
                }
+               if (handlep->poll_breakloop_fd != -1) {
+                       /* Close the eventfd; we do not need it in nonblock mode. */
+                       close(handlep->poll_breakloop_fd);
+                       handlep->poll_breakloop_fd = -1;
+               }
        } else {
+               if (handlep->poll_breakloop_fd == -1) {
+                       /* If we did not have an eventfd, open one now that we are blocking. */
+                       if ( ( handlep->poll_breakloop_fd = eventfd(0, EFD_NONBLOCK) ) == -1 ) {
+                               int save_errno = errno;
+                               snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+                                               "Could not open eventfd: %s",
+                                               strerror(errno));
+                               errno = save_errno;
+                               return -1;
+                       }
+               }
                if (handlep->timeout < 0) {
                        handlep->timeout = ~handlep->timeout;
                }
@@@ -3419,10 -3439,24 +3439,24 @@@ static int pcap_wait_for_frames_mmap(pc
        struct ifreq ifr;
        int ret;
        struct pollfd pollinfo[2];
+       int numpollinfo;
        pollinfo[0].fd = handle->fd;
        pollinfo[0].events = POLLIN;
-       pollinfo[1].fd = handlep->poll_breakloop_fd;
-       pollinfo[1].events = POLLIN;
+       if ( handlep->poll_breakloop_fd == -1 ) {
+               numpollinfo = 1;
+               pollinfo[1].revents = 0;
+               /*
+                * We set pollinfo[1].revents to zero, even though
+                * numpollinfo = 1 meaning that poll() doesn't see
+                * pollinfo[1], so that we do not have to add a
+                * conditional of numpollinfo > 1 below when we
+                * test pollinfo[1].revents.
+                */
+       } else {
+               pollinfo[1].fd = handlep->poll_breakloop_fd;
+               pollinfo[1].events = POLLIN;
+               numpollinfo = 2;
+       }
  
        /*
         * Keep polling until we either get some packets to read, see
                        if (timeout != 0)
                                timeout = 1;
                }
-               ret = poll(pollinfo, 2, timeout);
+               ret = poll(pollinfo, numpollinfo, timeout);
                if (ret < 0) {
                        /*
                         * Error.  If it's not EINTR, report it.
@@@ -3944,7 -3978,7 +3978,7 @@@ static int pcap_handle_packet_mmap
                        } else {
                                /*
                                 * Clear CANFD_FDF if it's set (probably
 -                               * again meaning that that field is
 +                               * again meaning that this field is
                                 * uninitialized junk).
                                 */
                                canhdr->fd_flags &= ~CANFD_FDF;
diff --combined testprogs/Makefile.in
index 0b4e99e60e301846c8f7f0d3559af3d3bd993bba,293ed88827147db253c0d0cc383e9c5cc103f613..f195693713f9c4fc8b913a5be5661dfed274fc99
@@@ -85,6 -85,7 +85,7 @@@ SRC = @VALGRINDTEST_SRC@ 
        findalldevstest-perf.c \
        findalldevstest.c \
        opentest.c \
+       nonblocktest.c \
        reactivatetest.c \
        selpolltest.c \
        threadsignaltest.c \
@@@ -101,7 -102,7 +102,7 @@@ all: $(TESTS
  
  capturetest: $(srcdir)/capturetest.c ../libpcap.a
        $(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/capturetest.c \
 -          ../libpcap.a $(LIBS) 
 +          ../libpcap.a $(LIBS)
  
  can_set_rfmon_test: $(srcdir)/can_set_rfmon_test.c ../libpcap.a
        $(CC) $(FULL_CFLAGS) -I. -L. -o can_set_rfmon_test \
@@@ -126,6 -127,10 +127,10 @@@ opentest: $(srcdir)/opentest.c ../libpc
        $(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/opentest.c \
            ../libpcap.a $(LIBS)
  
+ nonblocktest: $(srcdir)/nonblocktest.c ../libpcap.a
+       $(CC) $(FULL_CFLAGS) -I. -L. -o nonblocktest $(srcdir)/nonblocktest.c \
+           ../libpcap.a $(LIBS)
  reactivatetest: $(srcdir)/reactivatetest.c ../libpcap.a
        $(CC) $(FULL_CFLAGS) -I. -L. -o reactivatetest \
            $(srcdir)/reactivatetest.c ../libpcap.a $(LIBS)