Tizen 2.0 Release
[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/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 {
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     {
49         // Add one extra characted for end of string null value
50         char *newBuffer = static_cast<char *>(::realloc(buffer, size + 1));
51
52         if (!newBuffer)
53         {
54             // Failed to realloc
55             ::free(buffer);
56             throw std::bad_alloc();
57         }
58
59         // Setup reallocated buffer
60         buffer = newBuffer;
61         ::memset(buffer, 0, size + 1);
62
63         // Try to retrieve error string
64 #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
65         // The XSI-compliant version of strerror_r() is provided if:
66         int result = ::strerror_r(error, buffer, size);
67
68         if (result == 0)
69         {
70             ScopedFree<char> scopedBufferFree(buffer);
71             return std::string(buffer);
72         }
73 #else
74         errno = 0;
75
76         // Otherwise, the GNU-specific version is provided.
77         char *result = ::strerror_r(error, buffer, size);
78
79         if (result != NULL)
80         {
81             ScopedFree<char> scopedBufferFree(buffer);
82             return std::string(result);
83         }
84 #endif
85
86         // Interpret errors
87         switch (errno)
88         {
89         case EINVAL:
90             // We got an invalid errno value
91             ::free(buffer);
92             ThrowMsg(InvalidErrnoValue, "Invalid errno value: " << error);
93
94         case ERANGE:
95             // Incease buffer size and retry
96             size <<= 1;
97             continue;
98
99         default:
100             Assert(0 && "Invalid errno value after call to strerror_r!");
101         }
102     }
103 }
104 } // namespace DPL