]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * Copyright Andrey Semashev 2016. | |
3 | * Distributed under the Boost Software License, Version 1.0. | |
4 | * (See accompanying file LICENSE_1_0.txt or copy at | |
5 | * http://www.boost.org/LICENSE_1_0.txt) | |
6 | */ | |
7 | /*! | |
8 | * \file posix/object_name.cpp | |
9 | * \author Andrey Semashev | |
10 | * \date 06.03.2016 | |
11 | * | |
12 | * \brief This header is the Boost.Log library implementation, see the library documentation | |
13 | * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. | |
14 | */ | |
15 | ||
16 | #include <boost/log/detail/config.hpp> | |
17 | #include <unistd.h> | |
18 | #include <sys/types.h> | |
19 | #if defined(__ANDROID__) && (__ANDROID_API__+0) < 21 | |
20 | #include <sys/syscall.h> | |
7c673cae FG |
21 | #endif |
22 | #if !defined(BOOST_LOG_NO_GETPWUID_R) | |
23 | #include <pwd.h> | |
24 | #endif | |
25 | #include <cstddef> | |
26 | #include <cstring> | |
27 | #include <limits> | |
28 | #include <string> | |
29 | #include <vector> | |
30 | #include <boost/move/utility_core.hpp> | |
31 | #include <boost/type_traits/make_unsigned.hpp> | |
32 | #include <boost/spirit/include/karma_uint.hpp> | |
33 | #include <boost/spirit/include/karma_generate.hpp> | |
34 | #include <boost/log/utility/ipc/object_name.hpp> | |
35 | #include <boost/log/detail/header.hpp> | |
36 | ||
37 | namespace karma = boost::spirit::karma; | |
38 | ||
39 | namespace boost { | |
40 | ||
41 | BOOST_LOG_OPEN_NAMESPACE | |
42 | ||
43 | namespace ipc { | |
44 | ||
45 | BOOST_LOG_ANONYMOUS_NAMESPACE { | |
46 | ||
47 | #if defined(__ANDROID__) && (__ANDROID_API__+0) < 21 | |
48 | // Until Android API version 21 NDK does not define getsid wrapper in libc, although there is the corresponding syscall | |
49 | inline pid_t getsid(pid_t pid) BOOST_NOEXCEPT | |
50 | { | |
51 | return static_cast< pid_t >(::syscall(__NR_getsid, pid)); | |
52 | } | |
53 | #endif | |
54 | ||
55 | //! Formats an integer identifier into the string | |
56 | template< typename Identifier > | |
57 | inline void format_id(Identifier id, std::string& str) | |
58 | { | |
59 | // Note: in the code below, avoid involving locale for string formatting to make sure the names are as stable as possible | |
60 | typedef typename boost::make_unsigned< Identifier >::type unsigned_id_t; | |
61 | char buf[std::numeric_limits< unsigned_id_t >::digits10 + 2]; | |
62 | char* p = buf; | |
63 | ||
64 | typedef karma::uint_generator< unsigned_id_t, 10 > unsigned_id_gen; | |
65 | karma::generate(p, unsigned_id_gen(), static_cast< unsigned_id_t >(id)); | |
66 | str.append(buf, p); | |
67 | } | |
68 | ||
69 | //! Returns a prefix string for a shared resource according to the scope | |
70 | std::string get_scope_prefix(object_name::scope ns) | |
71 | { | |
72 | std::string prefix = "/boost.log."; | |
73 | switch (ns) | |
74 | { | |
75 | case object_name::process_group: | |
76 | { | |
77 | prefix.append("pgid."); | |
92f5a8d4 | 78 | #if !defined(BOOST_LOG_NO_GETPGRP) |
7c673cae | 79 | format_id(getpgrp(), prefix); |
92f5a8d4 TL |
80 | #else |
81 | format_id(getuid(), prefix); | |
82 | #endif | |
7c673cae FG |
83 | } |
84 | break; | |
85 | ||
86 | case object_name::session: | |
87 | { | |
88 | prefix.append("sid."); | |
92f5a8d4 | 89 | #if !defined(BOOST_LOG_NO_GETSID) |
7c673cae | 90 | format_id(getsid(0), prefix); |
92f5a8d4 TL |
91 | #else |
92 | format_id(getuid(), prefix); | |
93 | #endif | |
7c673cae FG |
94 | } |
95 | break; | |
96 | ||
97 | case object_name::user: | |
98 | { | |
99 | const uid_t uid = getuid(); | |
100 | ||
101 | #if !defined(BOOST_LOG_NO_GETPWUID_R) | |
102 | long limit = sysconf(_SC_GETPW_R_SIZE_MAX); | |
103 | if (limit <= 0) | |
104 | limit = 65536; | |
105 | std::vector< char > string_storage; | |
106 | string_storage.resize(static_cast< std::size_t >(limit)); | |
107 | passwd pwd = {}, *result = NULL; | |
108 | ||
109 | try | |
110 | { | |
111 | const int err = getpwuid_r(uid, &pwd, &string_storage[0], string_storage.size(), &result); | |
112 | if (err == 0 && result && result->pw_name) | |
113 | { | |
114 | prefix += "user."; | |
115 | prefix += result->pw_name; | |
116 | } | |
117 | else | |
118 | { | |
119 | prefix += "uid."; | |
120 | format_id(uid, prefix); | |
121 | } | |
122 | ||
123 | // Avoid leaving sensitive data in memory, if there is any | |
124 | std::memset(&pwd, 0, sizeof(pwd)); | |
125 | std::memset(&string_storage[0], 0, string_storage.size()); | |
126 | } | |
127 | catch (...) | |
128 | { | |
129 | std::memset(&pwd, 0, sizeof(pwd)); | |
130 | std::memset(&string_storage[0], 0, string_storage.size()); | |
131 | throw; | |
132 | } | |
133 | #else | |
134 | prefix += "uid."; | |
135 | format_id(uid, prefix); | |
136 | #endif | |
137 | } | |
138 | break; | |
139 | ||
140 | default: | |
141 | prefix += "global"; | |
142 | break; | |
143 | } | |
144 | ||
145 | prefix.push_back('.'); | |
146 | ||
147 | return BOOST_LOG_NRVO_RESULT(prefix); | |
148 | } | |
149 | ||
150 | } // namespace | |
151 | ||
152 | //! Constructor from the object name | |
153 | BOOST_LOG_API object_name::object_name(scope ns, const char* str) : | |
154 | m_name(get_scope_prefix(ns) + str) | |
155 | { | |
156 | } | |
157 | ||
158 | //! Constructor from the object name | |
159 | BOOST_LOG_API object_name::object_name(scope ns, std::string const& str) : | |
160 | m_name(get_scope_prefix(ns) + str) | |
161 | { | |
162 | } | |
163 | ||
164 | } // namespace ipc | |
165 | ||
166 | BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
167 | ||
168 | } // namespace boost | |
169 | ||
170 | #include <boost/log/detail/footer.hpp> |