/src/brpc/src/butil/errno.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | // Date: Fri Sep 10 13:34:25 CST 2010 |
19 | | |
20 | | #include "butil/build_config.h" // OS_MACOSX |
21 | | #include <errno.h> // errno |
22 | | #include <string.h> // strerror_r |
23 | | #include <stdlib.h> // EXIT_FAILURE |
24 | | #include <stdio.h> // snprintf |
25 | | #include <pthread.h> // pthread_mutex_t |
26 | | #include <unistd.h> // _exit |
27 | | #include "butil/scoped_lock.h" // BAIDU_SCOPED_LOCK |
28 | | |
29 | | namespace butil { |
30 | | |
31 | | const int ERRNO_BEGIN = -32768; |
32 | | const int ERRNO_END = 32768; |
33 | | static const char* errno_desc[ERRNO_END - ERRNO_BEGIN] = {}; |
34 | | static pthread_mutex_t modify_desc_mutex = PTHREAD_MUTEX_INITIALIZER; |
35 | | |
36 | | const size_t ERROR_BUFSIZE = 64; |
37 | | __thread char tls_error_buf[ERROR_BUFSIZE]; |
38 | | |
39 | | int DescribeCustomizedErrno( |
40 | 50 | int error_code, const char* error_name, const char* description) { |
41 | 50 | BAIDU_SCOPED_LOCK(modify_desc_mutex); |
42 | 50 | if (error_code < ERRNO_BEGIN || error_code >= ERRNO_END) { |
43 | | // error() is a non-portable GNU extension that should not be used. |
44 | 0 | fprintf(stderr, "Fail to define %s(%d) which is out of range, abort.", |
45 | 0 | error_name, error_code); |
46 | 0 | _exit(1); |
47 | 0 | } |
48 | 50 | const char* desc = errno_desc[error_code - ERRNO_BEGIN]; |
49 | 50 | if (desc) { |
50 | 0 | if (strcmp(desc, description) == 0) { |
51 | 0 | fprintf(stderr, "WARNING: Detected shared library loading\n"); |
52 | 0 | return -1; |
53 | 0 | } |
54 | 50 | } else { |
55 | | #if defined(OS_MACOSX) |
56 | | const int rc = strerror_r(error_code, tls_error_buf, ERROR_BUFSIZE); |
57 | | if (rc != EINVAL) |
58 | | #else |
59 | 50 | desc = strerror_r(error_code, tls_error_buf, ERROR_BUFSIZE); |
60 | 50 | if (desc && strncmp(desc, "Unknown error", 13) != 0) |
61 | 0 | #endif |
62 | 0 | { |
63 | 0 | fprintf(stderr, "WARNING: Fail to define %s(%d) which is already defined as `%s'", |
64 | 0 | error_name, error_code, desc); |
65 | 0 | } |
66 | 50 | } |
67 | 50 | errno_desc[error_code - ERRNO_BEGIN] = description; |
68 | 50 | return 0; // must |
69 | 50 | } |
70 | | |
71 | | } // namespace butil |
72 | | |
73 | 0 | const char* berror(int error_code) { |
74 | 0 | if (error_code == -1) { |
75 | 0 | return "General error -1"; |
76 | 0 | } |
77 | 0 | if (error_code >= butil::ERRNO_BEGIN && error_code < butil::ERRNO_END) { |
78 | 0 | const char* s = butil::errno_desc[error_code - butil::ERRNO_BEGIN]; |
79 | 0 | if (s) { |
80 | 0 | return s; |
81 | 0 | } |
82 | | #if defined(OS_MACOSX) |
83 | | const int rc = strerror_r(error_code, butil::tls_error_buf, butil::ERROR_BUFSIZE); |
84 | | if (rc == 0 || rc == ERANGE/*bufsize is not long enough*/) { |
85 | | return butil::tls_error_buf; |
86 | | } |
87 | | #else |
88 | 0 | s = strerror_r(error_code, butil::tls_error_buf, butil::ERROR_BUFSIZE); |
89 | 0 | if (s) { |
90 | 0 | return s; |
91 | 0 | } |
92 | 0 | #endif |
93 | 0 | } |
94 | 0 | snprintf(butil::tls_error_buf, butil::ERROR_BUFSIZE, |
95 | 0 | "Unknown error %d", error_code); |
96 | 0 | return butil::tls_error_buf; |
97 | 0 | } |
98 | | |
99 | 0 | const char* berror() { |
100 | 0 | return berror(errno); |
101 | 0 | } |