Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules_mobile / core / src / errno_string.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        errno_string.h
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of errno string
21  */
22 #include <stddef.h>
23 #include <dpl/errno_string.h>
24 #include <dpl/assert.h>
25 #include <dpl/exception.h>
26 #include <dpl/assert.h>
27 #include <dpl/scoped_free.h>
28 #include <string>
29 #include <cstddef>
30 #include <cstring>
31 #include <malloc.h>
32 #include <cerrno>
33 #include <stdexcept>
34
35 namespace DPL {
36 namespace // anonymous
37 {
38 const size_t DEFAULT_ERRNO_STRING_SIZE = 32;
39 } // namespace anonymous
40
41 std::string GetErrnoString(int error)
42 {
43     size_t size = DEFAULT_ERRNO_STRING_SIZE;
44     char *buffer = NULL;
45
46     for (;;) {
47         // Add one extra characted for end of string null value
48         char *newBuffer = static_cast<char *>(::realloc(buffer, size + 1));
49
50         if (!newBuffer) {
51             // Failed to realloc
52             ::free(buffer);
53             throw std::bad_alloc();
54         }
55
56         // Setup reallocated buffer
57         buffer = newBuffer;
58         ::memset(buffer, 0, size + 1);
59
60         // Try to retrieve error string
61 #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
62         // The XSI-compliant version of strerror_r() is provided if:
63         int result = ::strerror_r(error, buffer, size);
64
65         if (result == 0) {
66             ScopedFree<char> scopedBufferFree(buffer);
67             return std::string(buffer);
68         }
69 #else
70         errno = 0;
71
72         // Otherwise, the GNU-specific version is provided.
73         char *result = ::strerror_r(error, buffer, size);
74
75         if (result != NULL) {
76             ScopedFree<char> scopedBufferFree(buffer);
77             return std::string(result);
78         }
79 #endif
80
81         // Interpret errors
82         switch (errno) {
83         case EINVAL:
84             // We got an invalid errno value
85                 ::free(buffer);
86             ThrowMsg(InvalidErrnoValue, "Invalid errno value: " << error);
87
88         case ERANGE:
89             // Incease buffer size and retry
90             size <<= 1;
91             continue;
92
93         default:
94             Assert(0 && "Invalid errno value after call to strerror_r!");
95         }
96     }
97 }
98 } // namespace DPL