Skip to content

Commit 2c4b887

Browse files
committed
Add special errno handling to libcxx
1 parent 0f486a1 commit 2c4b887

File tree

10 files changed

+235
-7
lines changed

10 files changed

+235
-7
lines changed

libc/integral/normalize.inc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,6 @@
8383
#define __BIGGEST_ALIGNMENT__ 16
8484
#endif
8585

86-
#ifdef _COSMO_SOURCE
87-
#define _PAGESIZE 4096
88-
#endif
89-
9086
#if defined(__LP64__) && !defined(__INT64_TYPE__)
9187
#include "libc/integral/lp64.inc"
9288
#elif defined(_MSC_VER) && !defined(__INT64_TYPE__)

third_party/libcxx/BUILD.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,7 @@ third_party/libcxx/fs/filesystem_clock.cpp \
10941094
third_party/libcxx/fs/filesystem_error.cpp \
10951095
third_party/libcxx/fs/int128_builtins.cpp \
10961096
third_party/libcxx/fs/operations.cpp \
1097+
third_party/libcxx/fs/cosmo.cpp \
10971098
third_party/libcxx/fs/path.cpp \
10981099
third_party/libcxx/ryu/d2fixed.cpp \
10991100
third_party/libcxx/ryu/d2s.cpp \

third_party/libcxx/README.cosmo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ ORIGIN
1111
LOCAL CHANGES
1212

1313
- Wrote __config_site
14+
- Add special handling for cosmo errno
1415
- Shaped and molded directory structure
15-
- Kludged (and probably broke) awful `cerr` feature

third_party/libcxx/__system_error/errc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
141141
// This leads to the odd pushing and popping of the deprecated
142142
// diagnostic.
143143
_LIBCPP_DECLARE_STRONG_ENUM(errc){
144-
address_family_not_supported, // = EAFNOSUPPORT,
144+
address_family_not_supported = 65536, // = EAFNOSUPPORT,
145145
address_in_use, // = EADDRINUSE,
146146
address_not_available, // = EADDRNOTAVAIL,
147147
already_connected, // = EISCONN,

third_party/libcxx/config_elast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#elif defined(__EMSCRIPTEN__)
3333
// No _LIBCPP_ELAST needed on Emscripten
3434
#elif defined(__COSMOPOLITAN__)
35-
#define _LIBCPP_ELAST 65535
35+
// No _LIBCPP_ELAST needed on Cosmopolitan
3636
#elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC)
3737
#define _LIBCPP_ELAST 4095
3838
#elif defined(__APPLE__)

third_party/libcxx/fs/cosmo.cpp

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#ifdef __COSMOPOLITAN__
2+
#include <filesystem>
3+
4+
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
5+
6+
namespace detail {
7+
8+
std::errc __cosmo_err_to_errc_impl(int err) {
9+
if (err == EAFNOSUPPORT) return errc::address_family_not_supported;
10+
if (err == EADDRINUSE) return errc::address_in_use;
11+
if (err == EADDRNOTAVAIL) return errc::address_not_available;
12+
if (err == EISCONN) return errc::already_connected;
13+
if (err == E2BIG) return errc::argument_list_too_long;
14+
if (err == EDOM) return errc::argument_out_of_domain;
15+
if (err == EFAULT) return errc::bad_address;
16+
if (err == EBADF) return errc::bad_file_descriptor;
17+
if (err == EBADMSG) return errc::bad_message;
18+
if (err == EPIPE) return errc::broken_pipe;
19+
if (err == ECONNABORTED) return errc::connection_aborted;
20+
if (err == EALREADY) return errc::connection_already_in_progress;
21+
if (err == ECONNREFUSED) return errc::connection_refused;
22+
if (err == ECONNRESET) return errc::connection_reset;
23+
if (err == EXDEV) return errc::cross_device_link;
24+
if (err == EDESTADDRREQ) return errc::destination_address_required;
25+
if (err == EBUSY) return errc::device_or_resource_busy;
26+
if (err == ENOTEMPTY) return errc::directory_not_empty;
27+
if (err == ENOEXEC) return errc::executable_format_error;
28+
if (err == EEXIST) return errc::file_exists;
29+
if (err == EFBIG) return errc::file_too_large;
30+
if (err == ENAMETOOLONG) return errc::filename_too_long;
31+
if (err == ENOSYS) return errc::function_not_supported;
32+
if (err == EHOSTUNREACH) return errc::host_unreachable;
33+
if (err == EIDRM) return errc::identifier_removed;
34+
if (err == EILSEQ) return errc::illegal_byte_sequence;
35+
if (err == ENOTTY) return errc::inappropriate_io_control_operation;
36+
if (err == EINTR) return errc::interrupted;
37+
if (err == EINVAL) return errc::invalid_argument;
38+
if (err == ESPIPE) return errc::invalid_seek;
39+
if (err == EIO) return errc::io_error;
40+
if (err == EISDIR) return errc::is_a_directory;
41+
if (err == EMSGSIZE) return errc::message_size;
42+
if (err == ENETDOWN) return errc::network_down;
43+
if (err == ENETRESET) return errc::network_reset;
44+
if (err == ENETUNREACH) return errc::network_unreachable;
45+
if (err == ENOBUFS) return errc::no_buffer_space;
46+
if (err == ECHILD) return errc::no_child_process;
47+
if (err == ENOLINK) return errc::no_link;
48+
if (err == ENOLCK) return errc::no_lock_available;
49+
if (err == ENOMSG) return errc::no_message;
50+
if (err == (ENODATA ? ENODATA : ENOMSG)) return errc::no_message_available;
51+
if (err == ENOPROTOOPT) return errc::no_protocol_option;
52+
if (err == ENOSPC) return errc::no_space_on_device;
53+
if (err == ENOMEM) return errc::not_enough_memory;
54+
if (err == (ENOSR ? ENOSR : ENOMEM)) return errc::no_stream_resources;
55+
if (err == ENXIO) return errc::no_such_device_or_address;
56+
if (err == ENODEV) return errc::no_such_device;
57+
if (err == ENOENT) return errc::no_such_file_or_directory;
58+
if (err == ESRCH) return errc::no_such_process;
59+
if (err == ENOTDIR) return errc::not_a_directory;
60+
if (err == ENOTSOCK) return errc::not_a_socket;
61+
if (err == (ENOSTR ? ENOSTR : EINVAL)) return errc::not_a_stream;
62+
if (err == ENOTCONN) return errc::not_connected;
63+
if (err == ENOTSUP) return errc::not_supported;
64+
if (err == ECANCELED) return errc::operation_canceled;
65+
if (err == EINPROGRESS) return errc::operation_in_progress;
66+
if (err == EPERM) return errc::operation_not_permitted;
67+
if (err == EOPNOTSUPP) return errc::operation_not_supported;
68+
if (err == EWOULDBLOCK) return errc::operation_would_block;
69+
if (err == EOWNERDEAD) return errc::owner_dead;
70+
if (err == EACCES) return errc::permission_denied;
71+
if (err == EPROTO) return errc::protocol_error;
72+
if (err == EPROTONOSUPPORT) return errc::protocol_not_supported;
73+
if (err == EROFS) return errc::read_only_file_system;
74+
if (err == EDEADLK) return errc::resource_deadlock_would_occur;
75+
if (err == EAGAIN) return errc::resource_unavailable_try_again;
76+
if (err == ERANGE) return errc::result_out_of_range;
77+
if (err == ENOTRECOVERABLE) return errc::state_not_recoverable;
78+
if (err == ETIME) return errc::stream_timeout;
79+
if (err == ETXTBSY) return errc::text_file_busy;
80+
if (err == ETIMEDOUT) return errc::timed_out;
81+
if (err == ENFILE) return errc::too_many_files_open_in_system;
82+
if (err == EMFILE) return errc::too_many_files_open;
83+
if (err == EMLINK) return errc::too_many_links;
84+
if (err == ELOOP) return errc::too_many_symbolic_link_levels;
85+
if (err == EOVERFLOW) return errc::value_too_large;
86+
if (err == EPROTOTYPE) return errc::wrong_protocol_type;
87+
return errc::not_supported;
88+
}
89+
90+
int __cosmo_errc_to_err_impl(std::errc err) {
91+
if (err == errc::address_family_not_supported) return EAFNOSUPPORT;
92+
if (err == errc::address_in_use) return EADDRINUSE;
93+
if (err == errc::address_not_available) return EADDRNOTAVAIL;
94+
if (err == errc::already_connected) return EISCONN;
95+
if (err == errc::argument_list_too_long) return E2BIG;
96+
if (err == errc::argument_out_of_domain) return EDOM;
97+
if (err == errc::bad_address) return EFAULT;
98+
if (err == errc::bad_file_descriptor) return EBADF;
99+
if (err == errc::bad_message) return EBADMSG;
100+
if (err == errc::broken_pipe) return EPIPE;
101+
if (err == errc::connection_aborted) return ECONNABORTED;
102+
if (err == errc::connection_already_in_progress) return EALREADY;
103+
if (err == errc::connection_refused) return ECONNREFUSED;
104+
if (err == errc::connection_reset) return ECONNRESET;
105+
if (err == errc::cross_device_link) return EXDEV;
106+
if (err == errc::destination_address_required) return EDESTADDRREQ;
107+
if (err == errc::device_or_resource_busy) return EBUSY;
108+
if (err == errc::directory_not_empty) return ENOTEMPTY;
109+
if (err == errc::executable_format_error) return ENOEXEC;
110+
if (err == errc::file_exists) return EEXIST;
111+
if (err == errc::file_too_large) return EFBIG;
112+
if (err == errc::filename_too_long) return ENAMETOOLONG;
113+
if (err == errc::function_not_supported) return ENOSYS;
114+
if (err == errc::host_unreachable) return EHOSTUNREACH;
115+
if (err == errc::identifier_removed) return EIDRM;
116+
if (err == errc::illegal_byte_sequence) return EILSEQ;
117+
if (err == errc::inappropriate_io_control_operation) return ENOTTY;
118+
if (err == errc::interrupted) return EINTR;
119+
if (err == errc::invalid_argument) return EINVAL;
120+
if (err == errc::invalid_seek) return ESPIPE;
121+
if (err == errc::io_error) return EIO;
122+
if (err == errc::is_a_directory) return EISDIR;
123+
if (err == errc::message_size) return EMSGSIZE;
124+
if (err == errc::network_down) return ENETDOWN;
125+
if (err == errc::network_reset) return ENETRESET;
126+
if (err == errc::network_unreachable) return ENETUNREACH;
127+
if (err == errc::no_buffer_space) return ENOBUFS;
128+
if (err == errc::no_child_process) return ECHILD;
129+
if (err == errc::no_link) return ENOLINK;
130+
if (err == errc::no_lock_available) return ENOLCK;
131+
if (err == errc::no_message) return ENOMSG;
132+
if (err == errc::no_message_available) return (ENODATA ? ENODATA : ENOMSG);
133+
if (err == errc::no_protocol_option) return ENOPROTOOPT;
134+
if (err == errc::no_space_on_device) return ENOSPC;
135+
if (err == errc::not_enough_memory) return ENOMEM;
136+
if (err == errc::no_stream_resources) return (ENOSR ? ENOSR : ENOMEM);
137+
if (err == errc::no_such_device_or_address) return ENXIO;
138+
if (err == errc::no_such_device) return ENODEV;
139+
if (err == errc::no_such_file_or_directory) return ENOENT;
140+
if (err == errc::no_such_process) return ESRCH;
141+
if (err == errc::not_a_directory) return ENOTDIR;
142+
if (err == errc::not_a_socket) return ENOTSOCK;
143+
if (err == errc::not_a_stream) return (ENOSTR ? ENOSTR : EINVAL);
144+
if (err == errc::not_connected) return ENOTCONN;
145+
if (err == errc::not_supported) return ENOTSUP;
146+
if (err == errc::operation_canceled) return ECANCELED;
147+
if (err == errc::operation_in_progress) return EINPROGRESS;
148+
if (err == errc::operation_not_permitted) return EPERM;
149+
if (err == errc::operation_not_supported) return EOPNOTSUPP;
150+
if (err == errc::operation_would_block) return EWOULDBLOCK;
151+
if (err == errc::owner_dead) return EOWNERDEAD;
152+
if (err == errc::permission_denied) return EACCES;
153+
if (err == errc::protocol_error) return EPROTO;
154+
if (err == errc::protocol_not_supported) return EPROTONOSUPPORT;
155+
if (err == errc::read_only_file_system) return EROFS;
156+
if (err == errc::resource_deadlock_would_occur) return EDEADLK;
157+
if (err == errc::resource_unavailable_try_again) return EAGAIN;
158+
if (err == errc::result_out_of_range) return ERANGE;
159+
if (err == errc::state_not_recoverable) return ENOTRECOVERABLE;
160+
if (err == errc::stream_timeout) return ETIME;
161+
if (err == errc::text_file_busy) return ETXTBSY;
162+
if (err == errc::timed_out) return ETIMEDOUT;
163+
if (err == errc::too_many_files_open_in_system) return ENFILE;
164+
if (err == errc::too_many_files_open) return EMFILE;
165+
if (err == errc::too_many_links) return EMLINK;
166+
if (err == errc::too_many_symbolic_link_levels) return ELOOP;
167+
if (err == errc::value_too_large) return EOVERFLOW;
168+
if (err == errc::wrong_protocol_type) return EPROTOTYPE;
169+
return ENOTSUP;
170+
}
171+
172+
std::errc __cosmo_err_to_errc(int err) {
173+
if (err >= 65536)
174+
return (std::errc)err;
175+
return __cosmo_err_to_errc_impl(err);
176+
}
177+
178+
int __cosmo_errc_to_err(std::errc err) {
179+
if ((int)err < 65536)
180+
return (int)err;
181+
return __cosmo_errc_to_err_impl(err);
182+
}
183+
184+
} // end namespace detail
185+
186+
_LIBCPP_END_NAMESPACE_FILESYSTEM
187+
188+
#endif // __COSMOPOLITAN__

third_party/libcxx/fs/directory_iterator.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,11 @@ class __dir_stream {
118118
if ((__stream_ = ::opendir(root.c_str())) == nullptr) {
119119
ec = detail::capture_errno();
120120
const bool allow_eacces = bool(opts & directory_options::skip_permission_denied);
121+
#ifdef __COSMOPOLITAN__
122+
if (allow_eacces && ec.value() == (int)errc::permission_denied)
123+
#else
121124
if (allow_eacces && ec.value() == EACCES)
125+
#endif
122126
ec.clear();
123127
return;
124128
}
@@ -307,7 +311,11 @@ bool recursive_directory_iterator::__try_recursion(error_code* ec) {
307311
}
308312
if (m_ec) {
309313
const bool allow_eacess = bool(__imp_->__options_ & directory_options::skip_permission_denied);
314+
#ifdef __COSMOPOLITAN__
315+
if (m_ec.value() == (int)errc::permission_denied && allow_eacess) {
316+
#else
310317
if (m_ec.value() == EACCES && allow_eacess) {
318+
#endif
311319
if (ec)
312320
ec->clear();
313321
} else {

third_party/libcxx/fs/error.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,16 @@ inline errc __win_err_to_errc(int err) {
9898

9999
#endif // _LIBCPP_WIN32API
100100

101+
errc __cosmo_err_to_errc(int);
102+
int __cosmo_errc_to_err(errc);
103+
101104
inline error_code capture_errno() {
102105
_LIBCPP_ASSERT_INTERNAL(errno != 0, "Expected errno to be non-zero");
106+
#ifdef __COSMOPOLITAN__
107+
return error_code((int)__cosmo_err_to_errc(errno), generic_category());
108+
#else
103109
return error_code(errno, generic_category());
110+
#endif
104111
}
105112

106113
#if defined(_LIBCPP_WIN32API)

third_party/libcxx/fs/file_descriptor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,12 @@ inline perms posix_get_perms(const StatT& st) noexcept { return static_cast<perm
194194
inline file_status create_file_status(error_code& m_ec, path const& p, const StatT& path_stat, error_code* ec) {
195195
if (ec)
196196
*ec = m_ec;
197+
#ifdef __COSMOPOLITAN__
198+
if (m_ec && (m_ec.value() == (int)errc::no_such_file_or_directory ||
199+
m_ec.value() == (int)errc::not_a_directory)) {
200+
#else
197201
if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
202+
#endif
198203
return file_status(file_type::not_found);
199204
} else if (m_ec) {
200205
ErrorHandler<void> err("posix_stat", ec, &p);

third_party/libcxx/system_error.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
# include <android/api-level.h>
2424
#endif
2525

26+
#ifdef __COSMOPOLITAN__
27+
#include <fs/error.h>
28+
#endif
29+
2630
_LIBCPP_BEGIN_NAMESPACE_STD
2731

2832
namespace {
@@ -35,6 +39,9 @@ string do_strerror_r(int ev);
3539

3640
# if defined(_LIBCPP_MSVCRT_LIKE)
3741
string do_strerror_r(int ev) {
42+
#ifdef __COSMOPOLITAN__
43+
ev = (int)filesystem::detail::__cosmo_errc_to_err(ev);
44+
#endif
3845
char buffer[strerror_buff_size];
3946
if (::strerror_s(buffer, strerror_buff_size, ev) == 0)
4047
return string(buffer);
@@ -81,6 +88,9 @@ string do_strerror_r(int ev) {
8188
// Preserve errno around the call. (The C++ standard requires that
8289
// system_error functions not modify errno).
8390
const int old_errno = errno;
91+
#ifdef __COSMOPOLITAN__
92+
ev = filesystem::detail::__cosmo_errc_to_err((errc)ev);
93+
#endif
8494
const char* error_message = handle_strerror_r_return(::strerror_r(ev, buffer, strerror_buff_size), buffer);
8595
// If we didn't get any message, print one now.
8696
if (!error_message[0]) {
@@ -129,6 +139,9 @@ class _LIBCPP_HIDDEN __generic_error_category : public __do_message {
129139
const char* __generic_error_category::name() const noexcept { return "generic"; }
130140

131141
string __generic_error_category::message(int ev) const {
142+
#ifdef __COSMOPOLITAN__
143+
ev = filesystem::detail::__cosmo_errc_to_err((errc)ev);
144+
#endif
132145
#ifdef _LIBCPP_ELAST
133146
if (ev > _LIBCPP_ELAST)
134147
return string("unspecified generic_category error");
@@ -156,6 +169,9 @@ class _LIBCPP_HIDDEN __system_error_category : public __do_message {
156169
const char* __system_error_category::name() const noexcept { return "system"; }
157170

158171
string __system_error_category::message(int ev) const {
172+
#ifdef __COSMOPOLITAN__
173+
ev = filesystem::detail::__cosmo_errc_to_err((errc)ev);
174+
#endif
159175
#ifdef _LIBCPP_ELAST
160176
if (ev > _LIBCPP_ELAST)
161177
return string("unspecified system_category error");
@@ -164,6 +180,9 @@ string __system_error_category::message(int ev) const {
164180
}
165181

166182
error_condition __system_error_category::default_error_condition(int ev) const noexcept {
183+
#ifdef __COSMOPOLITAN__
184+
ev = filesystem::detail::__cosmo_errc_to_err((errc)ev);
185+
#endif
167186
#ifdef _LIBCPP_ELAST
168187
if (ev > _LIBCPP_ELAST)
169188
return error_condition(ev, system_category());
@@ -212,7 +231,11 @@ system_error::~system_error() noexcept {}
212231

213232
void __throw_system_error(int ev, const char* what_arg) {
214233
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
234+
#ifdef __COSMOPOLITAN__
235+
std::__throw_system_error(error_code((int)filesystem::detail::__cosmo_err_to_errc(ev), system_category()), what_arg);
236+
#else
215237
std::__throw_system_error(error_code(ev, system_category()), what_arg);
238+
#endif
216239
#else
217240
// The above could also handle the no-exception case, but for size, avoid referencing system_category() unnecessarily.
218241
_LIBCPP_VERBOSE_ABORT(

0 commit comments

Comments
 (0)