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)
8 * \file posix/object_name.cpp
9 * \author Andrey Semashev
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.
16 #include <boost/log/detail/config.hpp>
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
26 #if !defined(BOOST_LOG_NO_GETPWUID_R)
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>
41 namespace karma
= boost::spirit::karma
;
45 BOOST_LOG_OPEN_NAMESPACE
49 BOOST_LOG_ANONYMOUS_NAMESPACE
{
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
55 return static_cast< pid_t
>(::syscall(__NR_getsid
, pid
));
59 //! Formats an integer identifier into the string
60 template< typename Identifier
>
61 inline void format_id(Identifier id
, std::string
& str
)
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];
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
));
73 //! Returns a prefix string for a shared resource according to the scope
74 std::string
get_scope_prefix(object_name::scope ns
)
76 std::string prefix
= "/boost.log.";
79 case object_name::process_group
:
81 prefix
.append("pgid.");
82 format_id(getpgrp(), prefix
);
86 case object_name::session
:
88 prefix
.append("sid.");
89 format_id(getsid(0), prefix
);
93 case object_name::user
:
95 const uid_t uid
= getuid();
97 #if !defined(BOOST_LOG_NO_GETPWUID_R)
98 long limit
= sysconf(_SC_GETPW_R_SIZE_MAX
);
101 std::vector
< char > string_storage
;
102 string_storage
.resize(static_cast< std::size_t >(limit
));
103 passwd pwd
= {}, *result
= NULL
;
107 const int err
= getpwuid_r(uid
, &pwd
, &string_storage
[0], string_storage
.size(), &result
);
108 if (err
== 0 && result
&& result
->pw_name
)
111 prefix
+= result
->pw_name
;
116 format_id(uid
, prefix
);
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());
125 std::memset(&pwd
, 0, sizeof(pwd
));
126 std::memset(&string_storage
[0], 0, string_storage
.size());
131 format_id(uid
, prefix
);
141 prefix
.push_back('.');
143 return BOOST_LOG_NRVO_RESULT(prefix
);
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
)
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
)
162 BOOST_LOG_CLOSE_NAMESPACE
// namespace log
166 #include <boost/log/detail/footer.hpp>