aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src/filesystem/operations.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-05-28Revert "[libc++] Introduce ABI sensitive areas to avoid requiring ↵James Y Knight1-2/+0
_LIBCPP_HIDE_FROM_ABI everywhere (#131156)" (#141756) This reverts commit c861fe8a71e64f3d2108c58147e7375cd9314521. Unfortunately, this use of hidden visibility attributes causes user-defined specializations of standard-library types to also be marked hidden by default, which is incorrect. See discussion thread on #131156. ...and also reverts the follow-up commits: Revert "[libc++] Add explicit ABI annotations to functions from the block runtime declared in <__functional/function.h> (#140592)" This reverts commit 3e4c9dc299c35155934688184319d391b298fff7. Revert "[libc++] Make ABI annotations explicit for windows-specific code (#140507)" This reverts commit f73287e623a6c2e4a3485832bc3e10860cd26eb5. Revert "[libc++][NFC] Replace a few "namespace std" with the correct macro (#140510)" This reverts commit 1d411f27c769a32cb22ce50b9dc4421e34fd40dd.
2025-05-18[libc++] Introduce ABI sensitive areas to avoid requiring ↵Nikolas Klauser1-0/+2
_LIBCPP_HIDE_FROM_ABI everywhere (#131156) This patch introduces `_LIBCPP_{BEGIN,END}_EXPLICIT_ABI_ANNOTATIONS`, which allow us to have implicit annotations for most functions, and just where it's not "hide_from_abi everything" we add explicit annotations. This allows us to drop the `_LIBCPP_HIDE_FROM_ABI` macro from most functions in libc++.
2025-05-12[libc++] Fix missing #includes (#130536)Matt1-0/+1
Adds missing includes that were detected when I tried to build libc++ as a module. Working towards #127012
2025-01-08[libcxx] Handle windows system error code mapping in std::error_code. (#93101)James Y Knight1-24/+25
The `std::error_code`/`std::error_category` functionality is designed to support multiple error domains. On Unix, both system calls and libc functions return the same error codes, and thus, libc++ today treats `generic_category()` and `system_category()` as being equivalent. However, on Windows, libc functions return `errno.h` error codes in the `errno` global, but system calls return the very different `winerror.h` error codes via `GetLastError()`. As such, there is a need to map the winerror.h error codes into generic errno codes. In libc++, however, the system_error facility does not implement this mapping; instead the mapping is hidden inside libc++, used directly by the std::filesystem implementation. That has a few problems: 1. For std::filesystem APIs, the concrete windows error number is lost, before users can see it. The intent of the distinction between std::error_code and std::error_condition is that the error_code return has the original (potentially more detailed) error code. 2. User-written code which calls Windows system APIs requires this same mapping, so it also can also return error_code objects that other (cross-platform) code can understand. After this commit, an `error_code` with `generic_category()` is used to report an error from `errno`, and, on Windows only, an `error_code` with `system_category()` is used to report an error from `GetLastError()`. On Unix, system_category remains identity-mapped to generic_category, but is never used by libc++ itself. The windows error code mapping is moved into system_error, so that conversion of an `error_code` to `error_condition` correctly translates the `system_category()` code into a `generic_category()` code, when appropriate. This allows code like: `error_code(GetLastError(), system_category()) == errc::invalid_argument` to work as expected -- as it does with MSVC STL. (Continued from old phabricator review [D151493](https://reviews.llvm.org/D151493))
2025-01-07[libcxx] Fix build for glibc < 2.27 (#121893)Yi Kong1-2/+10
PR #109211 introduced a build break on systems with glibc < 2.27, since copy_file_range was only introduced after that version. A version check is added to prevent this breakage.
2025-01-07[libc++] Fix largefile handling in fs::copy_file (#121855)Jannik Glückert1-0/+6
Fix for issues reported in https://github.com/llvm/llvm-project/pull/109211
2025-01-06[libc++] Use copy_file_range for fs::copy (#109211)Jannik Glückert1-33/+139
This optimizes `std::filesystem::copy_file` to use the `copy_file_range` syscall (Linux and FreeBSD) when available. It allows for reflinks on filesystems such as btrfs, zfs and xfs, and server-side copy for network filesystems such as NFS.
2024-09-05[libc++][NFC] Increase consistency for namespace closing commentsLouis Dionne1-3/+3
2024-06-25[libc++] Get the GCC build mostly clean of warnings (#96604)Nikolas Klauser1-2/+2
The GCC build has gotten to the point where it's often hard to find the actual error in the build log. We should look into enabling these warnings again in the future, but it looks like a lot of them are bogous.
2024-06-12[libcxx] Correct and clean-up filesystem operations error_code paths (#88341)Rodrigo Salazar1-13/+15
3 error_code related cleanups/corrections in the std::filesystem operations functions. 1. In `__copy`, the `ec->clear()` is unnecessary as `ErrorHandler` at the start of each function clears the error_code as part of its initialization. 2. In `__copy`, in the recursive codepath we are not checking the error_code result of `it.increment(m_ec2)` immediately after use in the for loop condition (and we aren't checking it after the final increment when we don't enter the loop). 3. In `__weakly_canonical`, it makes calls to `__canonical` (which internally uses OS APIs implementing POSIX `realpath`) and we are not checking the error code result from the `__canonical` call. Both `weakly_canonical` and `canonical` are supposed to set the error_code when underlying OS APIs result in an error (https://eel.is/c++draft/fs.err.report#3.1). With this change we propagate up the error_code from `__canonical` caused by any underlying OS API failure up to the `__weakly_canonical`. Essentially, if `__canonical` thinks an error code should be set, then `__weakly_canonical` must as well. Before this change it would be throwing an exception in the non-error_code form of the function when `__canonical` fails, while not setting the error code in the error_code form of the function (an inconsistency). Added a little coverage in weakly_canonical.pass.cpp for the error_code forms of the API that was missing. Though I am lacking utilities in libcxx testing to add granular testing of the failure scenarios (like forcing realpath to fail for a given path, as it could if you had something like a flaky remote filesystem).
2024-06-11[libc++] Fix UB in filesystem::__copy for non-existent destination. (#87615)Afanasyev Ivan1-3/+3
The lstat/stat/fstat functions have no guarantee whether the `struct stat` buffer is changed or not on failure. The filesystem::__copy function assumes that the `struct stat` buffer is not updated on failure, which is not necessarily correct. It appears that for a non-existing destination `detail::posix_lstat(to, t_st, &m_ec1)` returns a failure indicator and overwrites the `struct stat` buffer with a garbage value, which is accidentally equal to the `f_st` from stack internals from the previous `detail::posix_lstat(from, f_st, &m_ec1)` call. file_type::not_found is a known status, so checking against `if (not status_known(t))` passes spuriously and execution continues. Then the __copy function returns errc::function_not_supported because stats are accidentally equivalent, which is incorrect. Before checking for `detail::stat_equivalent`, we instead need to make sure that the call to lstat/stat/fstat was successful. As a result of `f_st` and `t_st` not being accessed anymore without checking for the lstat/stat/fstat success indicator, it is not needed to zero-initialize them.
2024-01-29[libc++] Fix filesystem::remove_all() on FreeBSD (#79540)Mark Johnston1-2/+3
remove_all_impl() opens the target path with O_NOFOLLOW, which fails if the target is a symbolic link. On FreeBSD, rather than returning ELOOP, openat() returns EMLINK. This is unlikely to change for compatibility reasons, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214633 . Thus, check for EMLINK as well.
2024-01-22[libc++][hardening] Classify assertions related to leaks and syscalls. (#77164)Konstantin Varlamov1-3/+18
Introduce two new categories: - `_LIBCPP_ASSERT_VALID_DEALLOCATION`; - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL`.
2024-01-20[libc++][hardening] Categorize assertions that produce incorrect results ↵Konstantin Varlamov1-3/+2
(#77183) Introduce a new `argument-within-domain` category that covers cases where the given arguments make it impossible to produce a correct result (or create a valid object in case of constructors). While the incorrect result doesn't create an immediate problem within the library (like e.g. a null pointer dereference would), it always indicates a logic error in user code and is highly likely to lead to a bug in the program once the value is used.
2023-12-18[libc++] Format the code base (#74334)Louis Dionne1-175/+148
This patch runs clang-format on all of libcxx/include and libcxx/src, in accordance with the RFC discussed at [1]. Follow-up patches will format the benchmarks, the test suite and remaining parts of the code. I'm splitting this one into its own patch so the diff is a bit easier to review. This patch was generated with: find libcxx/include libcxx/src -type f \ | grep -v 'module.modulemap.in' \ | grep -v 'CMakeLists.txt' \ | grep -v 'README.txt' \ | grep -v 'libcxx.imp' \ | grep -v '__config_site.in' \ | xargs clang-format -i A Git merge driver is available in libcxx/utils/clang-format-merge-driver.sh to help resolve merge and rebase issues across these formatting changes. [1]: https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all
2023-06-28[libc++][hardening][NFC] Introduce `_LIBCPP_ASSERT_UNCATEGORIZED`.varconst1-4/+4
Replace most uses of `_LIBCPP_ASSERT` with `_LIBCPP_ASSERT_UNCATEGORIZED`. This is done as a prerequisite to introducing hardened mode to libc++. The idea is to make enabling assertions an opt-in with (somewhat) fine-grained controls over which categories of assertions are enabled. The vast majority of assertions are currently uncategorized; the new macro will allow turning on `_LIBCPP_ASSERT` (the underlying mechanism for all kinds of assertions) without enabling all the uncategorized assertions (in the future; this patch preserves the current behavior). Differential Revision: https://reviews.llvm.org/D153816
2023-06-26[libc++][filesystem] Avoid using anonymous namespaces in support headersLouis Dionne1-1/+1
This avoids using anonymous namespaces in headers and ensures that the various helper functions get deduplicated across the TUs implementing <filesystem>. Otherwise, we'd get a definition of these helper functions in each TU where they are used, which is entirely unnecessary. Differential Revision: https://reviews.llvm.org/D152378
2023-06-19[libc++] Split sources for <filesystem>Louis Dionne1-1139/+6
The operations.cpp file contained the implementation of a ton of functionality unrelated to just the filesystem operations, and filesystem_common.h contained a lot of unrelated functionality as well. Splitting this up into more files will make it possible in the future to support parts of <filesystem> (e.g. path) on systems where there is no notion of a filesystem. Differential Revision: https://reviews.llvm.org/D152377
2023-06-12[libc++] Android temp dir is /data/local/tmp, enable Windows testRyan Prichard1-1/+6
[libc++] Android temp dir is /data/local/tmp, enable Windows test On Android, std::filesystem::temp_directory_path() should fall back to /data/local/tmp when no environment variable is set. There is no /tmp directory. Most apps can't access /data/local/tmp, but they do have a "cache dir" (Context#getCacheDir()) that is usable for temporary files. However, there is no obvious and reliable way for libc++ to query this directory in contexts where it is available. The global fallback /data/local/tmp is available for "adb shell", making it useful for test suites. On Windows, temp_directory_path falls back to the Windows directory (e.g. "C:\Windows"), so call GetWindowsDirectoryW to do the test. Reviewed By: ldionne, #libc, enh Differential Revision: https://reviews.llvm.org/D137131
2022-10-03[libc++] Suppress -Wctad-maybe-unsupported on types w/o deduction guidesLouis Dionne1-0/+1
There are a handful of standard library types that are intended to support CTAD but don't need any explicit deduction guides to do so. This patch adds a dummy deduction guide to those types to suppress -Wctad-maybe-unsupported (which gets emitted in user code). This is a re-application of the original patch by Eric Fiselier in fcd549a7d828 which had been reverted due to reasons lost at this point. I also added the macro to a few more types. Reviving this patch was prompted by the discussion on https://llvm.org/D133425. Differential Revision: https://reviews.llvm.org/D133535
2022-09-16[SystemZ][z/OS] define REMOVE_ALL_USE_DIRECTORY_ITERATOR (libc++)Muiez Ahmed1-1/+1
This patch fixes the z/OS build by using the first implementation of __remove_all since we don't have access to the openat() family of POSIX functions. Differential Revision: https://reviews.llvm.org/D132948
2022-05-05Fix "the the" typo in documentation and user facing stringsBrian Tracy1-1/+1
There are many more instances of this pattern, but I chose to limit this change to .rst files (docs), anything in libcxx/include, and string literals. These have the highest chance of being seen by end users. Reviewed By: #libc, Mordante, martong, ldionne Differential Revision: https://reviews.llvm.org/D124708
2022-04-08[libc++] Rename PS() macro to avoid clashing with Xtensa register nameGustavo Henrique Nihei1-20/+20
This patch addresses a clash with the PS register from Xtensa defined in the <specreg.h> header file, which is commonly included in OS implementation. Issue identified while building libc++ port for Apache NuttX, targeting Xtensa-based chips (e.g. Espressif's ESP32). Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com> Differential Revision: https://reviews.llvm.org/D122479
2022-02-28[libc++] Fix double file closing in `std::filesystem::remove_all()`.Konstantin Varlamov1-1/+3
According to Linux documentation (see e.g. https://linux.die.net/man/3/closedir): > A successful call to `closedir()` also closes the underlying file > descriptor associated with `dirp`. Thus, calling `close()` after a successful call to `closedir()` is at best redundant. Worse, should a different thread open a file in-between the calls to `closedir()` and `close()` and get the same file descriptor, the call to `close()` might actually close a different file than was intended. rdar://89251874 Differential Revision: https://reviews.llvm.org/D120453
2022-02-16[libc++] Move everything related solely to _LIBCPP_ASSERT to its own fileLouis Dionne1-0/+1
This is the first step towards disentangling the debug mode and assertions in libc++. This patch doesn't make any functional change: it simply moves _LIBCPP_ASSERT-related stuff to its own file so as to make it clear that libc++ assertions and the debug mode are different things. Future patches will make it possible to enable assertions without enabling the debug mode. Differential Revision: https://reviews.llvm.org/D119769
2022-02-15[libc++] Replace `#include ""` with `<>` in libcxx/src/. NFCI.Arthur O'Dwyer1-9/+9
Our best guess is that the two syntaxes should have exactly equivalent effects, so, let's be consistent with what we do in libcxx/include/. I've left `#include "include/x.h"` and `#include "../y.h"` alone because I'm less sure that they're interchangeable, and they aren't inconsistent with libcxx/include/ because libcxx/include/ never does that kind of thing. Also, use the `_LIBCPP_PUSH_MACROS/POP_MACROS` dance for `<__undef_macros>`, even though it's technically unnecessary in a standalone .cpp file, just so we have consistently one way to do it. Differential Revision: https://reviews.llvm.org/D119561
2022-02-14[libc++] Implement P0627R6 (Function to mark unreachable code)Nikolas Klauser1-8/+9
Reviewed By: ldionne, Quuxplusone, #libc Spies: arichardson, mstorsjo, libcxx-commits, mgorny Differential Revision: https://reviews.llvm.org/D119152
2022-02-01[libc++] Fix TOCTOU issue with std::filesystem::remove_allLouis Dionne1-1/+106
https://bugs.chromium.org/p/llvm/issues/detail?id=19 rdar://87912416 Differential Revision: https://reviews.llvm.org/D118134
2021-11-17[runtimes][NFC] Remove filenames at the top of the license noticeLouis Dionne1-1/+1
We've stopped doing it in libc++ for a while now because these names would end up rotting as we move things around and copy/paste stuff. This cleans up all the existing files so as to stop the spreading as people copy-paste headers around.
2021-05-25[libcxx] Fix the function name in exceptions from create_directoriesMartin Storsjö1-1/+4
If the nested create_directory call fails, we'd still want to re-report the errors with the create_directories function name, which is what the caller called. This fixes one aspect from MS STL's tests for std::filesystem. Differential Revision: https://reviews.llvm.org/D102365
2021-05-23[libc++] use more early returns for consistencyJoerg Sonnenberger1-10/+7
Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D96983
2021-03-16[libc++] Improve src/filesystem's formatting of paths.Arthur O'Dwyer1-16/+9
This is my attempt to merge D98077 (bugfix the format strings for Windows paths, which use wchar_t not char) and D96986 (replace C++ variadic templates with C-style varargs so that `__attribute__((format(printf)))` can be applied, for better safety) and D98065 (remove an unused function overload). The one intentional functional change here is in `__create_what`. It now prints path1 and path2 in square-brackets _and_ double-quotes, rather than just square-brackets. Prior to this patch, it would print either path double-quoted if-and-only-if it was the empty string. Now the double-quotes are always present. I doubt anybody's code is relying on the current format, right? Differential Revision: https://reviews.llvm.org/D98097
2021-03-05[libcxx] Map ERROR_BAD_PATHNAME to errc::no_such_file_or_directory on windowsMartin Storsjö1-0/+1
Opening a path like \\server (without a trailing share name and path) produces this error, while opening e.g. \\server\share (for a nonexistent server/share) produces ERROR_BAD_NETPATH (which already is mapped). This happens in some testcases (in fs.op.proximate); as proximate() calls weakly_canonical() on the inputs, weakly_canonical() checks whether the path exists or not. When the error code wasn't recognized (it mapped to errc::invalid_argument), the stat operation wasn't conclusive and weakly_canonical() errored out. With the proper error code mapping, this isn't considered an error, just a nonexistent path, and weakly_canonical() can proceed. This roughly matches what MS STL does - it doesn't have ERROR_BAD_PATHNAME in its error code mapping table, but it checks for this error code specifically in the return of their correspondence of the stat function. Differential Revision: https://reviews.llvm.org/D97619
2021-03-05[libcxx] Avoid infinite recursion in create_directories, if the root ↵Martin Storsjö1-0/+2
directory doesn't exist Differential Revision: https://reviews.llvm.org/D97618
2021-03-02[libcxx] Explicitly return the expected error code in create_directories if ↵Martin Storsjö1-1/+2
the parent isn't a directory On windows, going ahead and actually trying to create the directory doesn't return an error code that maps to std::errc::not_a_directory in this case. This fixes two cases of TEST_CHECK(ErrorIs(ec, std::errc::not_a_directory)) in filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp for windows (in testcases added in 59c72a70121567f7aee347e96b4ac8f3cfe9f4b2). Differential Revision: https://reviews.llvm.org/D97090
2021-02-26[libcxx] Use the allocating form of getcwd() on Glibc and Apple platformsMartin Storsjö1-1/+1
This avoids having to query pathconf for a max size for preallocating a buffer for the return value. This is an extension to the POSIX getcwd() spec. Differential Revision: https://reviews.llvm.org/D97460
2021-02-20[libcxx] Rename a method in PathParser for clarity. NFC.Martin Storsjö1-6/+7
Differential Revision: https://reviews.llvm.org/D97081
2021-02-19[libcxx] Have lexically_normal return the path with preferred separatorsMartin Storsjö1-0/+1
Differential Revision: https://reviews.llvm.org/D91179
2021-02-18libcxx: use early returnsJoerg Sonnenberger1-11/+9
Differential Revision: https://reviews.llvm.org/D96955
2021-02-17[libcxx] Implement parsing of root_name for paths on windowsMartin Storsjö1-7/+85
Differential Revision: https://reviews.llvm.org/D91176
2021-02-05[libcxx] Implement temp_directory_path using GetTempPath on windowsMartin Storsjö1-0/+14
This does roughly the same as the manual implementation, but checks a slightly different set of environment variables and has a more appropriate fallback if no environment variables are available (/tmp isn't a very useful fallback on windows). Differential Revision: https://reviews.llvm.org/D91175
2021-02-05[libcxx] Use the posix code for directory_entry::__do_refreshMartin Storsjö1-43/+0
This works just fine for windows, as all the functions it calls are implemented and wrapped for windows. Differential Revision: https://reviews.llvm.org/D91173
2021-02-03[libcxx] Implement the read_symlink function for windowsMartin Storsjö1-6/+10
Differential Revision: https://reviews.llvm.org/D91172
2021-02-03[libcxx] Implement the permissions function for windowsMartin Storsjö1-7/+3
Differential Revision: https://reviews.llvm.org/D91171
2021-02-02[libcxx] Implement the canonical function for windowsMartin Storsjö1-7/+7
Differential Revision: https://reviews.llvm.org/D91170
2021-02-02[libcxx] Implement the current_path function for windowsMartin Storsjö1-4/+21
Differential Revision: https://reviews.llvm.org/D91169
2021-02-02[libcxx] Implement the space function for windowsMartin Storsjö1-2/+2
Differential Revision: https://reviews.llvm.org/D91168
2021-01-29[libcxx] Hook up a number of operation functions to their windows counterpartsMartin Storsjö1-19/+22
Use the corresponding wchar functions, named "_wfunc" instead of "func", where feasible, or reimplement functions with native windows APIs. Differential Revision: https://reviews.llvm.org/D91143
2021-01-29[libcxx] Implement _FilesystemClock::now() and __last_write_time for windowsMartin Storsjö1-2/+21
Differential Revision: https://reviews.llvm.org/D91142
2021-01-29[libcxx] Implement the stat function family on top of native windows APIsMartin Storsjö1-4/+6
While the windows CRTs (the modern UCRT, and the legacy msvcrt.dll that mingw still often defaults to) do provide stat functions, they're a bit lacking - they only provide second precision on the modification time, lack support for symlinks and a few other details. Instead reimplement them using a couple windows native functions, getting exactly the info we need. (Technically, the implementation within the CRT calls these functions anyway.) If we only need a few fields, we could also do with fewer calls, as a later optimization. Differential Revision: https://reviews.llvm.org/D91141