diff options
author | Guy Harris <gharris@sonic.net> | 2022-08-25 11:25:09 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-25 11:25:09 -0700 |
commit | 9019f5332a3ca20fd99a220914f6ea89873c5dcc (patch) | |
tree | 5f3e26a10cc2a1547344b101c79df9b63e8a2321 /pcap-linux.c | |
parent | 3ffafc08164300a8a4c7cd66780a31c05e6a9707 (diff) | |
parent | 024fd9717d43835f3e08b3146714532768910d3c (diff) |
Merge pull request #1113 from fenner/no-eventfd
Close the eventfd if we are non-blocking
Diffstat (limited to 'pcap-linux.c')
-rw-r--r-- | pcap-linux.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/pcap-linux.c b/pcap-linux.c index 8ceffde1..43d2a9f0 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -842,7 +842,10 @@ static void pcap_cleanup_linux( pcap_t *handle ) 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 @@ static void pcap_breakloop_linux(pcap_t *handle) 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)); } /* @@ -3375,7 +3379,23 @@ pcap_setnonblock_linux(pcap_t *handle, int nonblock) */ 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 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle) 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 @@ -3487,7 +3521,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle) 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. |