Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::asio vs. libpcap: avoid calling close twice

When running strace on the following program:

#include <boost/asio.hpp>
#include <pcap.h>

using namespace boost;

int main(int argc, char* argv[])
{
    asio::io_service io;
    asio::posix::stream_descriptor stream(io);
    char errorBuffer[BUFSIZ];
    pcap_t* p = pcap_open_live("any", BUFSIZ, false, 0, errorBuffer);
    stream.assign(pcap_get_selectable_fd(p));
    io.run();
    stream.close();
    pcap_close(p);
    return 0;
}

I get:

close(6)                                = 0
setsockopt(6, SOL_PACKET, PACKET_RX_RING, {block_size=0, block_nr=0, frame_size=0, frame_nr=0}, 16) = -1 EBADF (Bad file descriptor)
munmap(0xb733c000, 4145152)             = 0
close(6)                                = -1 EBADF (Bad file descriptor)

As you can see, close is called twice on the same fd (first by stream.close(), then by pcap_close(p)). While the program might not make sense, I need to call both stream.close() (to prevent io_service from calling epoll_ctl on a closed fd) and pcap_close(p) (to release the memory used by the pcap_t) - this happens on a multithreaded program.

Any ideas on how to do this without calling close on the same fd twice?

like image 290
bruno nery Avatar asked Nov 29 '25 08:11

bruno nery


1 Answers

A posix::stream_descriptor assumes ownership of the descriptor, it will close it when going out of scope. To resolve the double close, duplicate the descriptor before assigning with dup().

like image 185
Sam Miller Avatar answered Nov 30 '25 22:11

Sam Miller