forked from facebook/watchman
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherror_category.cpp
135 lines (116 loc) · 4.39 KB
/
error_category.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Copyright 2016-present Facebook, Inc.
* Licensed under the Apache License, Version 2.0 */
#include "watchman.h"
#include "watchman_error_category.h"
using std::generic_category;
namespace watchman {
const char* error_category::name() const noexcept {
return "watchman";
}
std::string error_category::message(int) const {
return "the programmer should not be trying to render an error message "
"using watchman::error_category, please report this bug!";
}
const std::error_category& error_category() {
static class error_category cat;
return cat;
}
const char* inotify_category::name() const noexcept {
return "inotify";
}
std::string inotify_category::message(int err) const {
switch (err) {
case EMFILE:
return "The user limit on the total number of inotify "
"instances has been reached; increase the "
"fs.inotify.max_user_instances sysctl";
case ENFILE:
return "The system limit on the total number of file descriptors "
"has been reached";
case ENOMEM:
return "Insufficient kernel memory is available";
case ENOSPC:
return "The user limit on the total number of inotify watches "
"was reached; increase the fs.inotify.max_user_watches sysctl";
default:
return std::generic_category().message(err);
}
}
const std::error_category& inotify_category() {
static class inotify_category cat;
return cat;
}
bool error_category::equivalent(const std::error_code& code, int condition)
const noexcept {
if (code.category() == inotify_category()) {
// Treat inotify the same as the generic category for the purposes of
// equivalence; it is the same namespace, we just provide different
// renditions of the error messages.
return equivalent(
std::error_code(code.value(), std::generic_category()), condition);
}
switch (static_cast<error_code>(condition)) {
case error_code::no_such_file_or_directory:
return
#ifdef _WIN32
code == windows_error_code(ERROR_FILE_NOT_FOUND) ||
code == windows_error_code(ERROR_DEV_NOT_EXIST) ||
#endif
code == make_error_code(std::errc::no_such_file_or_directory);
case error_code::not_a_directory:
return
#ifdef _WIN32
code == windows_error_code(ERROR_PATH_NOT_FOUND) ||
code == windows_error_code(ERROR_DIRECTORY) ||
#endif
code == make_error_code(std::errc::not_a_directory);
case error_code::is_a_directory:
return code == make_error_code(std::errc::is_a_directory);
#ifdef ESTALE
case error_code::stale_file_handle:
return code == std::error_code(ESTALE, std::generic_category());
#endif
case error_code::too_many_symbolic_link_levels:
// POSIX says open with O_NOFOLLOW should set errno to ELOOP if the path
// is a symlink. However, FreeBSD (which ironically originated O_NOFOLLOW)
// sets it to EMLINK. So we check for either condition here.
return code ==
make_error_code(std::errc::too_many_symbolic_link_levels) ||
code == make_error_code(std::errc::too_many_links);
case error_code::permission_denied:
return
#ifdef _WIN32
code == windows_error_code(ERROR_ACCESS_DENIED) ||
code == windows_error_code(ERROR_INVALID_ACCESS) ||
code == windows_error_code(ERROR_WRITE_PROTECT) ||
code == windows_error_code(ERROR_SHARING_VIOLATION) ||
#endif
code == make_error_code(std::errc::permission_denied) ||
code == make_error_code(std::errc::operation_not_permitted);
case error_code::system_limits_exceeded:
return
#ifdef _WIN32
code == windows_error_code(ERROR_TOO_MANY_OPEN_FILES) ||
#endif
code == make_error_code(std::errc::too_many_files_open_in_system) ||
code == make_error_code(std::errc::no_space_on_device) ||
code == make_error_code(std::errc::not_enough_memory) ||
code == make_error_code(std::errc::too_many_files_open);
case error_code::timed_out:
return
#ifdef _WIN32
code == windows_error_code(ERROR_TIMEOUT) ||
code == windows_error_code(WAIT_TIMEOUT) ||
#endif
code == make_error_code(std::errc::timed_out);
case error_code::not_a_symlink:
return
#ifdef _WIN32
code == windows_error_code(ERROR_NOT_A_REPARSE_POINT) ||
#endif
code == make_error_code(std::errc::invalid_argument);
default:
return false;
}
}
}