| 3006 | } |
| 3007 | |
| 3008 | BOOST_FILESYSTEM_DECL |
| 3009 | bool copy_file(path const& from, path const& to, copy_options options, error_code* ec) |
| 3010 | { |
| 3011 | BOOST_ASSERT((((options & copy_options::overwrite_existing) != copy_options::none) + |
| 3012 | ((options & copy_options::skip_existing) != copy_options::none) + |
| 3013 | ((options & copy_options::update_existing) != copy_options::none)) <= 1); |
| 3014 | |
| 3015 | if (ec) |
| 3016 | ec->clear(); |
| 3017 | |
| 3018 | #if defined(BOOST_FILESYSTEM_POSIX_API) |
| 3019 | |
| 3020 | int err = 0; |
| 3021 | |
| 3022 | // Note: Declare fd wrappers here so that errno is not clobbered by close() that may be called in fd wrapper destructors |
| 3023 | boost::scope::unique_fd infile, outfile; |
| 3024 | |
| 3025 | while (true) |
| 3026 | { |
| 3027 | infile.reset(::open(from.c_str(), O_RDONLY | O_CLOEXEC)); |
| 3028 | if (BOOST_UNLIKELY(!infile)) |
| 3029 | { |
| 3030 | err = errno; |
| 3031 | if (err == EINTR) |
| 3032 | continue; |
| 3033 | |
| 3034 | fail: |
| 3035 | emit_error(err, from, to, ec, "boost::filesystem::copy_file"); |
| 3036 | return false; |
| 3037 | } |
| 3038 | |
| 3039 | break; |
| 3040 | } |
| 3041 | |
| 3042 | #if defined(BOOST_FILESYSTEM_USE_STATX) |
| 3043 | unsigned int statx_data_mask = STATX_TYPE | STATX_MODE | STATX_INO | STATX_SIZE; |
| 3044 | if ((options & copy_options::update_existing) != copy_options::none) |
| 3045 | statx_data_mask |= STATX_MTIME; |
| 3046 | |
| 3047 | struct ::statx from_stat; |
| 3048 | if (BOOST_UNLIKELY(invoke_statx(infile.get(), "", AT_EMPTY_PATH | AT_NO_AUTOMOUNT, statx_data_mask, &from_stat) < 0)) |
| 3049 | { |
| 3050 | fail_errno: |
| 3051 | err = errno; |
| 3052 | goto fail; |
| 3053 | } |
| 3054 | |
| 3055 | if (BOOST_UNLIKELY((from_stat.stx_mask & statx_data_mask) != statx_data_mask)) |
| 3056 | { |
| 3057 | err = ENOSYS; |
| 3058 | goto fail; |
| 3059 | } |
| 3060 | #else |
| 3061 | struct ::stat from_stat; |
| 3062 | if (BOOST_UNLIKELY(::fstat(infile.get(), &from_stat) != 0)) |
| 3063 | { |
| 3064 | fail_errno: |
| 3065 | err = errno; |
no test coverage detected