File: error_category.cpp

package info (click to toggle)
watchman 4.9.0-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,992 kB
  • sloc: cpp: 27,459; python: 6,538; java: 3,404; php: 3,257; ansic: 2,803; javascript: 1,116; makefile: 671; ruby: 364; sh: 124; xml: 102; lisp: 4
file content (125 lines) | stat: -rw-r--r-- 4,129 bytes parent folder | download | duplicates (3)
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
/* 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::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::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;
  }
}
}