1 /*
2 * Copyright (C) 2009 Tommi Maekitalo
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * As a special exception, you may use this file as part of a free
10 * software library without restriction. Specifically, if other files
11 * instantiate templates or use macros or inline functions from this
12 * file, or you compile this file and link it with other files to
13 * produce an executable, this file does not by itself cause the
14 * resulting executable to be covered by the GNU General Public
15 * License. This exception does not however invalidate any other
16 * reasons why the executable file might be covered by the GNU Library
17 * General Public License.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 *
28 */
29
30 #include "error.h"
31 #include <sstream>
32 #include <vector>
33 #include <string.h>
34
35 namespace cxxtools
36 {
37
38 namespace
39 {
40 // XSI compliant strerror_r
errorOut(int (* errfn)(int,char *,size_t),std::ostream & out,int errnum)41 inline void errorOut(int (*errfn)(int, char*, size_t), std::ostream& out, int errnum)
42 {
43 std::vector<char> buffer(512);
44 while (errfn(errnum, &buffer[0], buffer.size()) != 0)
45 {
46 if (errno != ERANGE)
47 {
48 out << "Unknown error " << errnum;
49 return;
50 }
51
52 buffer.resize(buffer.size() * 2);
53 }
54
55 out << &buffer[0];
56 }
57
58 // GNU specific strerror_r
errorOut(char * (* errfn)(int,char *,size_t),std::ostream & out,int errnum)59 inline void errorOut(char* (*errfn)(int, char*, size_t), std::ostream& out, int errnum)
60 {
61 std::vector<char> buffer(512);
62 while (true)
63 {
64 char* f = errfn(errnum, &buffer[0], buffer.size());
65 if (f != &buffer[0])
66 {
67 out << f;
68 return;
69 }
70
71 if (strlen(&buffer[0]) < buffer.size() - 1)
72 break;
73
74 buffer.resize(buffer.size() * 2);
75 }
76
77 out << &buffer[0];
78 }
79
errorOut(std::ostream & out,int errnum)80 inline void errorOut(std::ostream& out, int errnum)
81 {
82 errorOut(strerror_r, out, errnum);
83 }
84 }
85
getErrnoString(int errnum)86 std::string getErrnoString(int errnum)
87 {
88 std::ostringstream msg;
89 msg << "errno " << errnum << ": ";
90 errorOut(msg, errnum);
91 return msg.str();
92 }
93
getErrnoString(int errnum,const char * fn)94 std::string getErrnoString(int errnum, const char* fn)
95 {
96 if (errnum != 0)
97 {
98 std::ostringstream msg;
99 msg << fn << ": errno " << errnum << ": ";
100 errorOut(msg, errnum);
101 return msg.str();
102 }
103 else
104 return fn;
105 }
106
107 }
108