1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include "tensorflow/core/platform/error.h"
17
18 #include <errno.h>
19 #include <string.h>
20
21 #include "tensorflow/core/platform/status.h"
22 #include "tensorflow/core/platform/strcat.h"
23
24 namespace tensorflow {
25 namespace {
26
ErrnoToCode(int err_number)27 error::Code ErrnoToCode(int err_number) {
28 error::Code code;
29 switch (err_number) {
30 case 0:
31 code = error::OK;
32 break;
33 case EINVAL: // Invalid argument
34 case ENAMETOOLONG: // Filename too long
35 case E2BIG: // Argument list too long
36 case EDESTADDRREQ: // Destination address required
37 case EDOM: // Mathematics argument out of domain of function
38 case EFAULT: // Bad address
39 case EILSEQ: // Illegal byte sequence
40 case ENOPROTOOPT: // Protocol not available
41 case ENOSTR: // Not a STREAM
42 case ENOTSOCK: // Not a socket
43 case ENOTTY: // Inappropriate I/O control operation
44 case EPROTOTYPE: // Protocol wrong type for socket
45 case ESPIPE: // Invalid seek
46 code = error::INVALID_ARGUMENT;
47 break;
48 case ETIMEDOUT: // Connection timed out
49 case ETIME: // Timer expired
50 code = error::DEADLINE_EXCEEDED;
51 break;
52 case ENODEV: // No such device
53 case ENOENT: // No such file or directory
54 case ENXIO: // No such device or address
55 case ESRCH: // No such process
56 code = error::NOT_FOUND;
57 break;
58 case EEXIST: // File exists
59 case EADDRNOTAVAIL: // Address not available
60 case EALREADY: // Connection already in progress
61 code = error::ALREADY_EXISTS;
62 break;
63 case EPERM: // Operation not permitted
64 case EACCES: // Permission denied
65 case EROFS: // Read only file system
66 code = error::PERMISSION_DENIED;
67 break;
68 case ENOTEMPTY: // Directory not empty
69 case EISDIR: // Is a directory
70 case ENOTDIR: // Not a directory
71 case EADDRINUSE: // Address already in use
72 case EBADF: // Invalid file descriptor
73 case EBUSY: // Device or resource busy
74 case ECHILD: // No child processes
75 case EISCONN: // Socket is connected
76 #if !defined(_WIN32) && !defined(__HAIKU__)
77 case ENOTBLK: // Block device required
78 #endif
79 case ENOTCONN: // The socket is not connected
80 case EPIPE: // Broken pipe
81 #if !defined(_WIN32)
82 case ESHUTDOWN: // Cannot send after transport endpoint shutdown
83 #endif
84 case ETXTBSY: // Text file busy
85 code = error::FAILED_PRECONDITION;
86 break;
87 case ENOSPC: // No space left on device
88 #if !defined(_WIN32)
89 case EDQUOT: // Disk quota exceeded
90 #endif
91 case EMFILE: // Too many open files
92 case EMLINK: // Too many links
93 case ENFILE: // Too many open files in system
94 case ENOBUFS: // No buffer space available
95 case ENODATA: // No message is available on the STREAM read queue
96 case ENOMEM: // Not enough space
97 case ENOSR: // No STREAM resources
98 #if !defined(_WIN32) && !defined(__HAIKU__)
99 case EUSERS: // Too many users
100 #endif
101 code = error::RESOURCE_EXHAUSTED;
102 break;
103 case EFBIG: // File too large
104 case EOVERFLOW: // Value too large to be stored in data type
105 case ERANGE: // Result too large
106 code = error::OUT_OF_RANGE;
107 break;
108 case ENOSYS: // Function not implemented
109 case ENOTSUP: // Operation not supported
110 case EAFNOSUPPORT: // Address family not supported
111 #if !defined(_WIN32)
112 case EPFNOSUPPORT: // Protocol family not supported
113 #endif
114 case EPROTONOSUPPORT: // Protocol not supported
115 #if !defined(_WIN32) && !defined(__HAIKU__)
116 case ESOCKTNOSUPPORT: // Socket type not supported
117 #endif
118 case EXDEV: // Improper link
119 code = error::UNIMPLEMENTED;
120 break;
121 case EAGAIN: // Resource temporarily unavailable
122 case ECONNREFUSED: // Connection refused
123 case ECONNABORTED: // Connection aborted
124 case ECONNRESET: // Connection reset
125 case EINTR: // Interrupted function call
126 #if !defined(_WIN32)
127 case EHOSTDOWN: // Host is down
128 #endif
129 case EHOSTUNREACH: // Host is unreachable
130 case ENETDOWN: // Network is down
131 case ENETRESET: // Connection aborted by network
132 case ENETUNREACH: // Network unreachable
133 case ENOLCK: // No locks available
134 case ENOLINK: // Link has been severed
135 #if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || \
136 defined(__HAIKU__))
137 case ENONET: // Machine is not on the network
138 #endif
139 code = error::UNAVAILABLE;
140 break;
141 case EDEADLK: // Resource deadlock avoided
142 #if !defined(_WIN32)
143 case ESTALE: // Stale file handle
144 #endif
145 code = error::ABORTED;
146 break;
147 case ECANCELED: // Operation cancelled
148 code = error::CANCELLED;
149 break;
150 // NOTE: If you get any of the following (especially in a
151 // reproducible way) and can propose a better mapping,
152 // please email the owners about updating this mapping.
153 case EBADMSG: // Bad message
154 case EIDRM: // Identifier removed
155 case EINPROGRESS: // Operation in progress
156 case EIO: // I/O error
157 case ELOOP: // Too many levels of symbolic links
158 case ENOEXEC: // Exec format error
159 case ENOMSG: // No message of the desired type
160 case EPROTO: // Protocol error
161 #if !defined(_WIN32) && !defined(__HAIKU__)
162 case EREMOTE: // Object is remote
163 #endif
164 code = error::UNKNOWN;
165 break;
166 default: {
167 code = error::UNKNOWN;
168 break;
169 }
170 }
171 return code;
172 }
173
174 } // namespace
175
IOError(const string & context,int err_number)176 Status IOError(const string& context, int err_number) {
177 auto code = ErrnoToCode(err_number);
178 return Status(code, strings::StrCat(context, "; ", strerror(err_number)));
179 }
180
181 #if defined(_WIN32)
182 namespace internal {
183
GetWindowsErrorMessage(DWORD err)184 std::string GetWindowsErrorMessage(DWORD err) {
185 LPSTR buffer = NULL;
186 DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
187 FORMAT_MESSAGE_IGNORE_INSERTS;
188 FormatMessageA(flags, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
189 reinterpret_cast<LPSTR>(&buffer), 0, NULL);
190 std::string message = buffer;
191 LocalFree(buffer);
192 return message;
193 }
194
195 } // namespace internal
196 #endif
197
198 } // namespace tensorflow
199