1 // Copyright 2019 Google LLC
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 // https://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 #include "sandboxed_api/util/strerror.h"
16
17 #include <string.h> // For strerror_r
18
19 #include <cerrno>
20 #include <cstddef>
21 #include <string>
22
23 #include "absl/base/attributes.h"
24 #include "absl/strings/str_format.h"
25
26 namespace sapi {
27 namespace {
28
29 // Only one of these overloads will be used in any given build, as determined by
30 // the return type of strerror_r(): char* (for GNU), or int (for XSI). See 'man
31 // strerror_r' for more details.
StrErrorR(char * (* strerror_r)(int,char *,size_t),int errnum,char * buf,size_t buflen)32 ABSL_ATTRIBUTE_UNUSED const char* StrErrorR(char* (*strerror_r)(int, char*,
33 size_t),
34 int errnum, char* buf,
35 size_t buflen) {
36 return strerror_r(errnum, buf, buflen);
37 }
38
39 // The XSI version (most portable).
StrErrorR(int (* strerror_r)(int,char *,size_t),int errnum,char * buf,size_t buflen)40 ABSL_ATTRIBUTE_UNUSED const char* StrErrorR(int (*strerror_r)(int, char*,
41 size_t),
42 int errnum, char* buf,
43 size_t buflen) {
44 if (strerror_r(errnum, buf, buflen)) {
45 *buf = '\0';
46 }
47 return buf;
48 }
49
50 } // namespace
51
RawStrError(int errnum,char * buf,size_t buflen)52 const char* RawStrError(int errnum, char* buf, size_t buflen) {
53 const int saved_errno = errno;
54 const char* str = StrErrorR(strerror_r, errnum, buf, buflen);
55 if (*str == '\0') {
56 absl::SNPrintF(buf, buflen, "Unknown error %d", errnum);
57 str = buf;
58 }
59 errno = saved_errno;
60 return str;
61 }
62
StrError(int errnum)63 std::string StrError(int errnum) {
64 char buf[100];
65 return RawStrError(errnum, buf, sizeof(buf));
66 }
67
68 } // namespace sapi
69