Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules / 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/free_deleter.h>
28 #include <memory>
29 #include <string>
30 #include <cstddef>
31 #include <cstring>
32 #include <malloc.h>
33 #include <cerrno>
34 #include <stdexcept>
35
36 namespace DPL {
37 namespace // anonymous
38 {
39 const size_t DEFAULT_ERRNO_STRING_SIZE = 32;
40 } // namespace anonymous
41
42 std::string GetErrnoString(int error)
43 {
44     size_t size = DEFAULT_ERRNO_STRING_SIZE;
45     char *buffer = NULL;
46
47     for (;;) {
48         // Add one extra characted for end of string null value
49         char *newBuffer = static_cast<char *>(::realloc(buffer, size + 1));
50
51         if (!newBuffer) {
52             // Failed to realloc
53             ::free(buffer);
54             throw std::bad_alloc();
55         }
56
57         // Setup reallocated buffer
58         buffer = newBuffer;
59         ::memset(buffer, 0, size + 1);
60
61         // Try to retrieve error string
62 #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
63         // The XSI-compliant version of strerror_r() is provided if:
64         int result = ::strerror_r(error, buffer, size);
65
66         if (result == 0) {
67             std::unique_ptr<char[],free_deleter> scopedBufferFree(buffer);
68             return std::string(buffer);
69         }
70 #else
71         errno = 0;
72
73         // Otherwise, the GNU-specific version is provided.
74         char *result = ::strerror_r(error, buffer, size);
75
76         if (result != NULL) {
77             std::unique_ptr<char[],free_deleter> scopedBufferFree(buffer);
78             return std::string(result);
79         }
80 #endif
81
82         // Interpret errors
83         switch (errno) {
84         case EINVAL:
85             // We got an invalid errno value
86                 ::free(buffer);
87             ThrowMsg(InvalidErrnoValue, "Invalid errno value: " << error);
88
89         case ERANGE:
90             // Incease buffer size and retry
91             size <<= 1;
92             continue;
93
94         default:
95             AssertMsg(0, "Invalid errno value after call to strerror_r!");
96         }
97     }
98 }
99 } // namespace DPL