Use configure-time check to detect dirent::d_type field support.

This potentially allows to support more C libraries that provide file
type information during directory iteration.
This commit is contained in:
Andrey Semashev 2023-06-03 20:15:59 +03:00
parent 5147a88edc
commit 571d178f4f
5 changed files with 47 additions and 10 deletions

View File

@ -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)
@ -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()

View File

@ -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

View File

@ -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 ;

View File

@ -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;
}

View File

@ -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;
@ -321,7 +312,7 @@ 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);