[libcxx-commits] [PATCH] D151493: [libcxx] Handle windows system error code mapping in std::error_code.

James Y Knight via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu May 25 13:46:48 PDT 2023


jyknight created this revision.
Herald added a project: All.
jyknight requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

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 winderr.h error codes into generic
errno codes. In libc++, however, the system_error facility does not
currently implement this mapping, and 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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151493

Files:
  libcxx/include/__filesystem/directory_entry.h
  libcxx/include/__system_error/system_error.h
  libcxx/src/filesystem/directory_iterator.cpp
  libcxx/src/filesystem/filesystem_common.h
  libcxx/src/filesystem/operations.cpp
  libcxx/src/filesystem/posix_compat.h
  libcxx/src/system_error.cpp
  libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp
  libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp
  libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
  libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp
  libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp
  libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
  libcxx/test/support/filesystem_test_helper.h

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151493.525780.patch
Type: text/x-patch
Size: 36259 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230525/1191bb22/attachment-0001.bin>


More information about the libcxx-commits mailing list