Skip to content

Commit

Permalink
Added config macros for disabling use of some system APIs.
Browse files Browse the repository at this point in the history
By defining these new config macros the user can configure the library
to avoid using some system APIs even if they are detected as available
by the library build scripts. This can be useful in case if the API
is known to consistently fail at runtime on the target system.

Related to #172.
  • Loading branch information
Lastique committed May 16, 2021
1 parent 4319cf1 commit 05de74a
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 27 deletions.
42 changes: 38 additions & 4 deletions build/Jamfile.v2
@@ -1,7 +1,7 @@
# Boost Filesystem Library Build Jamfile

# (C) Copyright Beman Dawes 2002-2006
# (C) Copyright Andrey Semashev 2020
# (C) Copyright Andrey Semashev 2020, 2021
# Distributed under the Boost Software License, Version 1.0.
# See www.boost.org/LICENSE_1_0.txt

Expand All @@ -15,14 +15,28 @@ lib advapi32 ;
lib coredll ;
explicit bcrypt advapi32 coredll ;

# The rule checks if a config macro is defined in the command line or build properties
rule has-config-flag ( flag : properties * )
{
if ( "<define>$(flag)" in $(properties) || "<define>$(flag)=1" in $(properties) )
{
return 1 ;
}
else
{
return ;
}
}

# The rule checks we're building for Windows and selects crypto API to be used
rule select-windows-crypto-api ( properties * )
{
local result ;

if <target-os>windows in $(properties) || <target-os>cygwin in $(properties)
{
if [ configure.builds ../config//has_bcrypt : $(properties) : "has BCrypt API" ]
if ! [ has-config-flag BOOST_FILESYSTEM_DISABLE_BCRYPT : $(properties) ] &&
[ configure.builds ../config//has_bcrypt : $(properties) : "has BCrypt API" ]
{
result = <define>BOOST_FILESYSTEM_HAS_BCRYPT <library>bcrypt ;
}
Expand All @@ -44,6 +58,27 @@ rule select-windows-crypto-api ( properties * )
return $(result) ;
}

# The rule checks if statx syscall is supported
rule check-statx ( properties * )
{
local result ;

if ! [ has-config-flag BOOST_FILESYSTEM_DISABLE_STATX : $(properties) ]
{
if [ configure.builds ../config//has_statx : $(properties) : "has statx" ]
{
result = <define>BOOST_FILESYSTEM_HAS_STATX ;
}
else if [ configure.builds ../config//has_statx_syscall : $(properties) : "has statx syscall" ]
{
result = <define>BOOST_FILESYSTEM_HAS_STATX_SYSCALL ;
}
}

#ECHO Result: $(result) ;
return $(result) ;
}

project boost/filesystem
: requirements
<host-os>hpux,<toolset>gcc:<define>_INCLUDE_STDC__SOURCE_199901
Expand All @@ -53,8 +88,7 @@ project boost/filesystem
[ check-target-builds ../config//has_stat_st_birthtim "has stat::st_birthtim" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIM ]
[ 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_statx "has statx" : <define>BOOST_FILESYSTEM_HAS_STATX ]
[ check-target-builds ../config//has_statx_syscall "has statx syscall" : <define>BOOST_FILESYSTEM_HAS_STATX_SYSCALL ]
<conditional>@check-statx
<conditional>@select-windows-crypto-api
: source-location ../src
: usage-requirements # pass these requirement to dependents (i.e. users)
Expand Down
34 changes: 32 additions & 2 deletions doc/index.htm
Expand Up @@ -243,7 +243,7 @@ <h2><a name="Implementation">Implementation</a></h2>
Microsoft Windows, SGI IRIX, and Sun Solaris operating systems using a variety
of compilers. It is also used by several smart phone operating systems.</p>
<h2><a name="Macros">Macros</a></h2>
<p>Users may defined the following macros if desired. Sensible defaults are
<p>Users may define the following macros if desired. Sensible defaults are
provided, so users can ignore these macros unless they have special needs.</p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
Expand All @@ -270,7 +270,37 @@ <h2><a name="Macros">Macros</a></h2>
<td valign="top">Boost.Filesystem library does not use the Boost auto-link
facility.</td>
</tr>
</table>
<tr>
<td valign="top"><code>BOOST_FILESYSTEM_DISABLE_SENDFILE</code></td>
<td valign="top">Not defined. <code>sendfile</code> API presence detected at library build time.</td>
<td valign="top">Boost.Filesystem library does not use the <code>sendfile</code> system call on Linux. The <code>sendfile</code> system call started accepting regular file descriptors as the target in Linux 2.6.33.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_FILESYSTEM_DISABLE_COPY_FILE_RANGE</code></td>
<td valign="top">Not defined. <code>copy_file_range</code> API presence detected at library build time.</td>
<td valign="top">Boost.Filesystem library does not use the <code>copy_file_range</code> system call on Linux. The <code>copy_file_range</code> system call was introduced in Linux kernel 4.5 and started operating across filesystems in 5.3.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_FILESYSTEM_DISABLE_STATX</code></td>
<td valign="top">Not defined. <code>statx</code> presence detected at library build time.</td>
<td valign="top">Boost.Filesystem library does not use the <code>statx</code> system call on Linux. The <code>statx</code> system call was introduced in Linux kernel 4.11.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_FILESYSTEM_DISABLE_GETRANDOM</code></td>
<td valign="top">Not defined. <code>getrandom</code> API presence detected at library build time.</td>
<td valign="top">Boost.Filesystem library does not use the <code>getrandom</code> system call on Linux. The <code>getrandom</code> system call was introduced in Linux kernel 3.17.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_FILESYSTEM_DISABLE_ARC4RANDOM</code></td>
<td valign="top">Not defined. <code>arc4random</code> API presence detected at library build time.</td>
<td valign="top">Boost.Filesystem library does not use the <code>arc4random_buf</code> system call on BSD systems. The <code>arc4random</code> API was introduced in OpenBSD 2.1 and FreeBSD 8.0.</td>
</tr>
<tr>
<td valign="top"><code>BOOST_FILESYSTEM_DISABLE_BCRYPT</code></td>
<td valign="top">Not defined. BCrypt API presence detected at library build time.</td>
<td valign="top">Boost.Filesystem library does not use the BCrypt API on Windows. Has no effect on other platforms.</td>
</tr>
</table>
<p>User-defined BOOST_POSIX_API and BOOST_WINDOWS_API macros are no longer
supported.</p>
<h2><a name="Building">Building</a> the object-library</h2>
Expand Down
5 changes: 5 additions & 0 deletions doc/release_history.html
Expand Up @@ -38,6 +38,11 @@
</td>
</table>

<h2>1.77.0</h2>
<ul>
<li>Added support for disabling usage of various system APIs at library build time. This can be useful when a certain API is detected as present by the library configuration scripts but must not be used for some reason (for example, when it is known to fail on the target system). See the description of <a href="index.htm#Macros">configuration macros</a> for more details.</li>
</ul>

<h2>1.76.0</h2>
<ul>
<li>Updated compatibility with <a href="https://wasi.dev/">WASI</a> platform. (<a href="https://github.com/boostorg/filesystem/pull/169">PR#169</a>)</li>
Expand Down
47 changes: 26 additions & 21 deletions src/operations.cpp
Expand Up @@ -77,15 +77,20 @@

#if defined(linux) || defined(__linux) || defined(__linux__)
#include <sys/utsname.h>
#include <sys/sendfile.h>
#include <sys/syscall.h>
#if !defined(BOOST_FILESYSTEM_DISABLE_SENDFILE)
#include <sys/sendfile.h>
#define BOOST_FILESYSTEM_USE_SENDFILE
#if defined(__NR_copy_file_range)
#endif // !defined(BOOST_FILESYSTEM_DISABLE_SENDFILE)
#if !defined(BOOST_FILESYSTEM_DISABLE_COPY_FILE_RANGE) && defined(__NR_copy_file_range)
#define BOOST_FILESYSTEM_USE_COPY_FILE_RANGE
#endif
#endif // !defined(BOOST_FILESYSTEM_DISABLE_COPY_FILE_RANGE) && defined(__NR_copy_file_range)
#if !defined(BOOST_FILESYSTEM_DISABLE_STATX) && (defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL))
#if !defined(BOOST_FILESYSTEM_HAS_STATX) && defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#include <linux/stat.h>
#endif
#define BOOST_FILESYSTEM_USE_STATX
#endif // !defined(BOOST_FILESYSTEM_DISABLE_STATX) && (defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL))
#endif // defined(linux) || defined(__linux) || defined(__linux__)

#if defined(BOOST_FILESYSTEM_HAS_STAT_ST_MTIM)
Expand Down Expand Up @@ -400,7 +405,7 @@ inline bool not_found_error(int errval) BOOST_NOEXCEPT
return errval == ENOENT || errval == ENOTDIR;
}

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)

//! Returns \c true if the two \c statx structures refer to the same file
inline bool equivalent_stat(struct ::statx const& s1, struct ::statx const& s2) BOOST_NOEXCEPT
Expand All @@ -420,7 +425,7 @@ inline uintmax_t get_size(struct ::statx const& st) BOOST_NOEXCEPT
return st.stx_size;
}

#else // defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#else // defined(BOOST_FILESYSTEM_USE_STATX)

//! Returns \c true if the two \c stat structures refer to the same file
inline bool equivalent_stat(struct ::stat const& s1, struct ::stat const& s2) BOOST_NOEXCEPT
Expand All @@ -442,7 +447,7 @@ inline uintmax_t get_size(struct ::stat const& st) BOOST_NOEXCEPT
return st.st_size;
}

#endif // defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#endif // defined(BOOST_FILESYSTEM_USE_STATX)

typedef int(copy_file_data_t)(int infile, int outfile, uintmax_t size);

Expand Down Expand Up @@ -1196,7 +1201,7 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod
break;
}

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
unsigned int statx_data_mask = STATX_TYPE | STATX_MODE | STATX_INO | STATX_SIZE;
if ((options & static_cast< unsigned int >(copy_options::update_existing)) != 0u)
statx_data_mask |= STATX_MTIME;
Expand Down Expand Up @@ -1290,7 +1295,7 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod
}
}

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
statx_data_mask = STATX_TYPE | STATX_MODE | STATX_INO;
if ((oflag & O_TRUNC) == 0)
{
Expand Down Expand Up @@ -1330,7 +1335,7 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod
{
// O_TRUNC is not set if copy_options::update_existing is set and an existing file was opened.
// We need to check the last write times.
#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
if (from_stat.stx_mtime.tv_sec < to_stat.stx_mtime.tv_sec || (from_stat.stx_mtime.tv_sec == to_stat.stx_mtime.tv_sec && from_stat.stx_mtime.tv_nsec <= to_stat.stx_mtime.tv_nsec))
return false;
#elif defined(BOOST_FILESYSTEM_STAT_ST_MTIMENSEC)
Expand Down Expand Up @@ -1517,7 +1522,7 @@ bool create_directory(path const& p, const path* existing, error_code* ec)
mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
if (existing)
{
#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx existing_stat;
if (BOOST_UNLIKELY(statx(AT_FDCWD, existing->c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &existing_stat) < 0))
{
Expand Down Expand Up @@ -1586,7 +1591,7 @@ void copy_directory(path const& from, path const& to, system::error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
int err;
struct ::statx from_stat;
if (BOOST_UNLIKELY(statx(AT_FDCWD, from.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &from_stat) < 0))
Expand Down Expand Up @@ -1748,7 +1753,7 @@ bool equivalent(path const& p1, path const& p2, system::error_code* ec)
#if defined(BOOST_POSIX_API)

// p2 is done first, so any error reported is for p1
#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx s2;
int e2 = statx(AT_FDCWD, p2.c_str(), AT_NO_AUTOMOUNT, STATX_INO, &s2);
if (BOOST_LIKELY(e2 == 0))
Expand Down Expand Up @@ -1856,7 +1861,7 @@ uintmax_t file_size(path const& p, error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx path_stat;
if (BOOST_UNLIKELY(statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_SIZE, &path_stat) < 0))
{
Expand Down Expand Up @@ -1919,7 +1924,7 @@ uintmax_t hard_link_count(path const& p, system::error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx path_stat;
if (BOOST_UNLIKELY(statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_NLINK, &path_stat) < 0))
{
Expand Down Expand Up @@ -1986,7 +1991,7 @@ bool is_empty(path const& p, system::error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx path_stat;
if (BOOST_UNLIKELY(statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_SIZE, &path_stat) < 0))
{
Expand Down Expand Up @@ -2041,7 +2046,7 @@ std::time_t creation_time(path const& p, system::error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx stx;
if (BOOST_UNLIKELY(statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_BTIME, &stx) < 0))
{
Expand Down Expand Up @@ -2097,7 +2102,7 @@ std::time_t last_write_time(path const& p, system::error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx stx;
if (BOOST_UNLIKELY(statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_MTIME, &stx) < 0))
{
Expand Down Expand Up @@ -2544,7 +2549,7 @@ file_status status(path const& p, error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx path_stat;
int err = statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat);
#else
Expand All @@ -2567,7 +2572,7 @@ file_status status(path const& p, error_code* ec)
return fs::file_status(fs::status_error);
}

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE)))
{
emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::status");
Expand Down Expand Up @@ -2649,7 +2654,7 @@ file_status symlink_status(path const& p, error_code* ec)

#if defined(BOOST_POSIX_API)

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
struct ::statx path_stat;
int err = statx(AT_FDCWD, p.c_str(), AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat);
#else
Expand All @@ -2672,7 +2677,7 @@ file_status symlink_status(path const& p, error_code* ec)
return fs::file_status(fs::status_error);
}

#if defined(BOOST_FILESYSTEM_HAS_STATX) || defined(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
#if defined(BOOST_FILESYSTEM_USE_STATX)
if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE)))
{
emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::symlink_status");
Expand Down
4 changes: 4 additions & 0 deletions src/unique_path.cpp
Expand Up @@ -25,13 +25,16 @@
#include <unistd.h>
#endif

#if !defined(BOOST_FILESYSTEM_DISABLE_ARC4RANDOM)
#if BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(2, 1, 0) || \
BOOST_OS_BSD_FREE >= BOOST_VERSION_NUMBER(8, 0, 0) || \
BOOST_LIB_C_CLOUDABI
#include <stdlib.h>
#define BOOST_FILESYSTEM_HAS_ARC4RANDOM
#endif
#endif // !defined(BOOST_FILESYSTEM_DISABLE_ARC4RANDOM)

#if !defined(BOOST_FILESYSTEM_DISABLE_GETRANDOM)
#if (defined(__linux__) || defined(__linux) || defined(linux)) && \
(!defined(__ANDROID__) || __ANDROID_API__ >= 28)
#include <sys/syscall.h>
Expand All @@ -51,6 +54,7 @@
#include <sys/random.h>
#endif
#endif // (defined(__linux__) || defined(__linux) || defined(linux)) && (!defined(__ANDROID__) || __ANDROID_API__ >= 28)
#endif // !defined(BOOST_FILESYSTEM_DISABLE_GETRANDOM)

#else // BOOST_WINDOWS_API

Expand Down

0 comments on commit 05de74a

Please sign in to comment.