Opened 6 years ago

Last modified 6 years ago

#12735 new Bugs

asio: Fails to include unistd.h if BOOST_ASIO_HAS_BOOST_CONFIG is defined

Reported by: Idar Tollefsen <idart@…> Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost Development Trunk Severity: Problem
Keywords: ASIO unistd.h Cc:

Description

uname -a:

Linux <hostname> 4.8.0-2-amd64 #1 SMP Devuan 4.8.11-1 (2016-12-02) x86_64 GNU/Linux

clang++ --version:

clang version 3.9.1-1 (tags/RELEASE_391/rc2)

libc++ version:

#define _LIBCPP_VERSION 1101

Compilation example;

clang++ -D_GNU_SOURCE -DBOOST_USER_CONFIG=\"boost_config.hpp\" -Drestrict=__restrict__ -pthread -O2 -g -Wall -Wextra -Wno-unknown-pragmas -Werror -Wformat-security -Woverloaded-virtual -Wwrite-strings -Wnon-virtual-dtor -Wno-mismatched-tags -Wno-tautological-constant-out-of-range-compare -Wno-gnu-designator -Wno-enum-conversion -fPIC -D__STDC_LIMIT_MACROS -std=gnu++11 -Wno-deprecated-declarations -stdlib=libc++ -c -o test.cpp.o test.cpp

Error message:

In file included from asio/local/stream_protocol.hpp:23:
In file included from asio/basic_socket_acceptor.hpp:19:
In file included from asio/basic_io_object.hpp:19:
In file included from asio/io_service.hpp:767:
In file included from asio/impl/io_service.hpp:71:
In file included from asio/detail/task_io_service.hpp:198:
In file included from asio/detail/impl/task_io_service.ipp:24:
In file included from asio/detail/reactor.hpp:21:
In file included from asio/detail/epoll_reactor.hpp:29:
In file included from asio/detail/select_interrupter.hpp:25:
In file included from asio/detail/eventfd_select_interrupter.hpp:80:
asio/detail/impl/eventfd_select_interrupter.ipp:78:9: error: use of undeclared identifier 'pipe'
    if (pipe(pipe_fds) == 0)
        ^
asio/detail/impl/eventfd_select_interrupter.ipp:104:7: error: no type named 'close' in the global namespace
    ::close(write_descriptor_);
    ~~^
asio/detail/impl/eventfd_select_interrupter.ipp:106:7: error: no type named 'close' in the global namespace
    ::close(read_descriptor_);
    ~~^
asio/detail/impl/eventfd_select_interrupter.ipp:122:18: error: no member named 'write' in the global namespace
  int result = ::write(write_descriptor_, &counter, sizeof(uint64_t));
               ~~^
asio/detail/impl/eventfd_select_interrupter.ipp:135:26: error: no member named 'read' in the global namespace
      int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t));
                       ~~^
asio/detail/impl/eventfd_select_interrupter.ipp:148:26: error: no member named 'read' in the global namespace
      int bytes_read = ::read(read_descriptor_, data, sizeof(data));
                       ~~^
asio/detail/impl/eventfd_select_interrupter.ipp:153:24: error: no member named 'read' in the global namespace
        bytes_read = ::read(read_descriptor_, data, sizeof(data));

Details:

Given the following abbreviated configuration file (called "boost_config.hpp" in the compilation example above) passed with -DBOOST_USER_CONFIG:

#define BOOST_NO_CONFIG
#define BOOST_BIND_NO_PLACEHOLDERS
#define BOOST_DISABLE_ABI_HEADERS
    
#define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp"
#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcpp.hpp"
    
#define BOOST_PLATFORM "linux"
    
#define BOOST_HAS_UNISTD_H

Then ASIO will, in detail/config.hpp, include <boost/config.hpp> and <boost/version.hpp> and define BOOST_ASIO_HAS_BOOST_CONFIG.

Further down in the same file, BOOST_ASIO_HAS_UNISTD_H decides whether it should include unistd.h or not.

The checks performed there fails to account for situations such as this where BOOST_ASIO_HAS_BOOST_CONFIG has been defined.

This probably works "as is" for the more popular combinations since they will pull in unistd.h through other configuration files (stdlib for example), but does not work for combinations that don't do that, such as Clang using libc++ on Linux.

Fix:

If BOOST_ASIO_HAS_BOOST_CONFIG is defined, check BOOST_HAS_UNISTD_H and define BOOST_ASIO_HAS_UNISTD_H accordingly so that unistd.h gets included when it should.

Attachments (1)

0001-Adds-BOOST_HAS_UNISTD_H-check-for-unistd.h-inclusion.patch (1.9 KB ) - added by Idar Tollefsen <idart@…> 6 years ago.

Download all attachments as: .zip

Change History (2)

by Idar Tollefsen <idart@…>, 6 years ago

comment:1 by Idar Tollefsen <idart@…>, 6 years ago

Ping on this. I'd appreciate some thoughts around this and the direction I took with the proposed patch.

From a quick glance, it's quite possible that the same applies to other BOOST_ASIO_* defines in detail/config.hpp that have corresponding BOOST_* counterparts.

An alternative workaround would be to define the necessary BOOST_ASIO_* defines alongside the existing BOOST_* defines I have in my config file, but that really looks like the wrong solution. It looks like unnecessary duplication and at the wrong level of abstraction when ASIO is used as part of Boost.

Note: See TracTickets for help on using tickets.