Showing with 95 additions and 23 deletions.
  1. +25 −9 .github/workflows/ci.yml
  2. +4 −0 CMakeLists.txt
  3. +1 −0 build/Jamfile.v2
  4. +2 −0 config/Jamfile.v2
  5. +39 −0 config/has_dirent_d_type.cpp
  6. +24 −14 src/directory.cpp
34 changes: 25 additions & 9 deletions .github/workflows/ci.yml
Expand Up @@ -241,37 +241,53 @@ jobs:
os: ubuntu-22.04
install:
- clang-15
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- toolset: clang
compiler: clang++-15
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu,2b-gnu"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
os: ubuntu-22.04
install:
- clang-15
- libc++-15-dev
- libc++abi-15-dev
- toolset: clang
compiler: clang++-16
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu,2b-gnu"
os: ubuntu-22.04
install:
- clang-16
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- toolset: clang
compiler: clang++-16
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu,2b-gnu"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
os: ubuntu-22.04
install:
- clang-16
- libc++-16-dev
- libc++abi-16-dev
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- name: UBSAN
toolset: clang
compiler: clang++-14
compiler: clang++-15
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu,2b-gnu"
cxxflags: -stdlib=libc++
linkflags: "-stdlib=libc++ -lubsan"
ubsan: 1
build_variant: debug
os: ubuntu-22.04
install:
- clang-14
- libc++-14-dev
- libc++abi-14-dev
- clang-15
- libc++-15-dev
- libc++abi-15-dev

- toolset: clang
cxxstd: "03,11,14,17,2a"
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Expand Up @@ -46,6 +46,7 @@ if(NOT BOOST_FILESYSTEM_DISABLE_STATX)
endif()
endif()
check_cxx_source_compiles("#include <${CMAKE_CURRENT_SOURCE_DIR}/config/has_fdopendir_nofollow.cpp>" BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
check_cxx_source_compiles("#include <${CMAKE_CURRENT_SOURCE_DIR}/config/has_dirent_d_type.cpp>" BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE)
check_cxx_source_compiles("#include <${CMAKE_CURRENT_SOURCE_DIR}/config/has_posix_at_apis.cpp>" BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
if(WIN32 AND NOT BOOST_FILESYSTEM_DISABLE_BCRYPT)
set(CMAKE_REQUIRED_LIBRARIES bcrypt)
Expand Down Expand Up @@ -199,6 +200,9 @@ endif()
if(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
target_compile_definitions(boost_filesystem PRIVATE BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
endif()
if(BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE)
target_compile_definitions(boost_filesystem PRIVATE BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE)
endif()
if(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
target_compile_definitions(boost_filesystem PRIVATE BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
endif()
Expand Down
1 change: 1 addition & 0 deletions build/Jamfile.v2
Expand Up @@ -134,6 +134,7 @@ project boost/filesystem
[ check-target-builds ../config//has_stat_st_birthtimensec "has stat::st_birthtimensec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMENSEC ]
[ check-target-builds ../config//has_stat_st_birthtimespec "has stat::st_birthtimespec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMESPEC ]
[ check-target-builds ../config//has_fdopendir_nofollow "has fdopendir(O_NOFOLLOW)" : <define>BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW ]
[ check-target-builds ../config//has_dirent_d_type "has dirent::d_type" : <define>BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE ]
[ check-target-builds ../config//has_posix_at_apis "has POSIX *at APIs" : <define>BOOST_FILESYSTEM_HAS_POSIX_AT_APIS ]
<conditional>@check-statx
<conditional>@select-windows-crypto-api
Expand Down
2 changes: 2 additions & 0 deletions config/Jamfile.v2
Expand Up @@ -29,6 +29,8 @@ obj has_stat_st_birthtimespec : has_stat_st_birthtimespec.cpp : <include>../src
explicit has_stat_st_birthtimespec ;
obj has_fdopendir_nofollow : has_fdopendir_nofollow.cpp : <include>../src ;
explicit has_fdopendir_nofollow ;
obj has_dirent_d_type : has_dirent_d_type.cpp : <include>../src ;
explicit has_dirent_d_type ;
obj has_posix_at_apis : has_posix_at_apis.cpp : <include>../src ;
explicit has_posix_at_apis ;

Expand Down
39 changes: 39 additions & 0 deletions config/has_dirent_d_type.cpp
@@ -0,0 +1,39 @@
// Copyright 2023 Andrey Semashev

// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt

// See library home page at http://www.boost.org/libs/filesystem

#include "platform_config.hpp"

#include <sys/types.h>
#include <dirent.h>

int main()
{
DIR* dir = opendir(".");
dirent* ent = readdir(dir);
switch (ent->d_type)
{
case DT_REG:
break;
case DT_DIR:
break;
case DT_LNK:
break;
case DT_SOCK:
break;
case DT_FIFO:
break;
case DT_BLK:
break;
case DT_CHR:
break;
case DT_UNKNOWN:
break;
default:
break;
}
return 0;
}
38 changes: 24 additions & 14 deletions src/directory.cpp
Expand Up @@ -74,15 +74,6 @@

#include <boost/filesystem/detail/header.hpp> // must be the last #include

// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in
// dir_itr_increment. The config tests are placed here because some of the
// macros being tested come from dirent.h.
//
// TODO: find out what macros indicate dirent::d_type present in more libraries
#if defined(BOOST_WINDOWS_API) || defined(_DIRENT_HAVE_D_TYPE) // defined by GNU C library if d_type present
#define BOOST_FILESYSTEM_STATUS_CACHE
#endif

namespace fs = boost::filesystem;
using boost::system::error_code;
using boost::system::system_category;
Expand Down Expand Up @@ -321,24 +312,43 @@ error_code dir_itr_increment(dir_itr_imp& imp, fs::path& filename, fs::file_stat

filename = result->d_name;

#ifdef BOOST_FILESYSTEM_STATUS_CACHE
#if defined(BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE)
if (result->d_type == DT_UNKNOWN) // filesystem does not supply d_type value
{
sf = symlink_sf = fs::file_status(fs::status_error);
}
else // filesystem supplies d_type value
{
if (result->d_type == DT_DIR)
sf = symlink_sf = fs::file_status(fs::directory_file);
else if (result->d_type == DT_REG)
if (result->d_type == DT_REG)
sf = symlink_sf = fs::file_status(fs::regular_file);
else if (result->d_type == DT_DIR)
sf = symlink_sf = fs::file_status(fs::directory_file);
else if (result->d_type == DT_LNK)
{
sf = fs::file_status(fs::status_error);
symlink_sf = fs::file_status(fs::symlink_file);
}
else
sf = symlink_sf = fs::file_status(fs::status_error);
{
switch (result->d_type)
{
case DT_SOCK:
sf = symlink_sf = fs::file_status(fs::socket_file);
break;
case DT_FIFO:
sf = symlink_sf = fs::file_status(fs::fifo_file);
break;
case DT_BLK:
sf = symlink_sf = fs::file_status(fs::block_file);
break;
case DT_CHR:
sf = symlink_sf = fs::file_status(fs::character_file);
break;
default:
sf = symlink_sf = fs::file_status(fs::status_error);
break;
}
}
}
#else
sf = symlink_sf = fs::file_status(fs::status_error);
Expand Down