]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/src/posix/object_name.cpp
0dfd7d4c59576b09dd6859130bb49d8704cbfdde
[ceph.git] / ceph / src / boost / libs / log / src / posix / object_name.cpp
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>
21 #if !defined(__CRYSTAX__)
22 // Until Android API version 21 Google NDK does not provide getpwuid_r
23 #define BOOST_LOG_NO_GETPWUID_R
24 #endif
25 #endif
26 #if !defined(BOOST_LOG_NO_GETPWUID_R)
27 #include <pwd.h>
28 #endif
29 #include <cstddef>
30 #include <cstring>
31 #include <limits>
32 #include <string>
33 #include <vector>
34 #include <boost/move/utility_core.hpp>
35 #include <boost/type_traits/make_unsigned.hpp>
36 #include <boost/spirit/include/karma_uint.hpp>
37 #include <boost/spirit/include/karma_generate.hpp>
38 #include <boost/log/utility/ipc/object_name.hpp>
39 #include <boost/log/detail/header.hpp>
40
41 namespace karma = boost::spirit::karma;
42
43 namespace boost {
44
45 BOOST_LOG_OPEN_NAMESPACE
46
47 namespace ipc {
48
49 BOOST_LOG_ANONYMOUS_NAMESPACE {
50
51 #if defined(__ANDROID__) && (__ANDROID_API__+0) < 21
52 // Until Android API version 21 NDK does not define getsid wrapper in libc, although there is the corresponding syscall
53 inline pid_t getsid(pid_t pid) BOOST_NOEXCEPT
54 {
55 return static_cast< pid_t >(::syscall(__NR_getsid, pid));
56 }
57 #endif
58
59 //! Formats an integer identifier into the string
60 template< typename Identifier >
61 inline void format_id(Identifier id, std::string& str)
62 {
63 // Note: in the code below, avoid involving locale for string formatting to make sure the names are as stable as possible
64 typedef typename boost::make_unsigned< Identifier >::type unsigned_id_t;
65 char buf[std::numeric_limits< unsigned_id_t >::digits10 + 2];
66 char* p = buf;
67
68 typedef karma::uint_generator< unsigned_id_t, 10 > unsigned_id_gen;
69 karma::generate(p, unsigned_id_gen(), static_cast< unsigned_id_t >(id));
70 str.append(buf, p);
71 }
72
73 //! Returns a prefix string for a shared resource according to the scope
74 std::string get_scope_prefix(object_name::scope ns)
75 {
76 std::string prefix = "/boost.log.";
77 switch (ns)
78 {
79 case object_name::process_group:
80 {
81 prefix.append("pgid.");
82 format_id(getpgrp(), prefix);
83 }
84 break;
85
86 case object_name::session:
87 {
88 prefix.append("sid.");
89 format_id(getsid(0), prefix);
90 }
91 break;
92
93 case object_name::user:
94 {
95 const uid_t uid = getuid();
96
97 #if !defined(BOOST_LOG_NO_GETPWUID_R)
98 long limit = sysconf(_SC_GETPW_R_SIZE_MAX);
99 if (limit <= 0)
100 limit = 65536;
101 std::vector< char > string_storage;
102 string_storage.resize(static_cast< std::size_t >(limit));
103 passwd pwd = {}, *result = NULL;
104
105 try
106 {
107 const int err = getpwuid_r(uid, &pwd, &string_storage[0], string_storage.size(), &result);
108 if (err == 0 && result && result->pw_name)
109 {
110 prefix += "user.";
111 prefix += result->pw_name;
112 }
113 else
114 {
115 prefix += "uid.";
116 format_id(uid, prefix);
117 }
118
119 // Avoid leaving sensitive data in memory, if there is any
120 std::memset(&pwd, 0, sizeof(pwd));
121 std::memset(&string_storage[0], 0, string_storage.size());
122 }
123 catch (...)
124 {
125 std::memset(&pwd, 0, sizeof(pwd));
126 std::memset(&string_storage[0], 0, string_storage.size());
127 throw;
128 }
129 #else
130 prefix += "uid.";
131 format_id(uid, prefix);
132 #endif
133 }
134 break;
135
136 default:
137 prefix += "global";
138 break;
139 }
140
141 prefix.push_back('.');
142
143 return BOOST_LOG_NRVO_RESULT(prefix);
144 }
145
146 } // namespace
147
148 //! Constructor from the object name
149 BOOST_LOG_API object_name::object_name(scope ns, const char* str) :
150 m_name(get_scope_prefix(ns) + str)
151 {
152 }
153
154 //! Constructor from the object name
155 BOOST_LOG_API object_name::object_name(scope ns, std::string const& str) :
156 m_name(get_scope_prefix(ns) + str)
157 {
158 }
159
160 } // namespace ipc
161
162 BOOST_LOG_CLOSE_NAMESPACE // namespace log
163
164 } // namespace boost
165
166 #include <boost/log/detail/footer.hpp>