/src/logging-log4cxx/src/main/cpp/system.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. See the NOTICE file distributed with |
4 | | * this work for additional information regarding copyright ownership. |
5 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | * (the "License"); you may not use this file except in compliance with |
7 | | * the License. You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | #include <log4cxx/logstring.h> |
19 | | #include <log4cxx/helpers/system.h> |
20 | | #include <log4cxx/helpers/filesystempath.h> |
21 | | |
22 | | #include <log4cxx/helpers/transcoder.h> |
23 | | #include <log4cxx/helpers/pool.h> |
24 | | #include <log4cxx/helpers/properties.h> |
25 | | #include <log4cxx/helpers/loglog.h> |
26 | | #include <log4cxx/helpers/stringhelper.h> |
27 | | #include <apr_file_io.h> |
28 | | #include <apr_user.h> |
29 | | #include <apr_env.h> |
30 | | |
31 | | #ifdef _WIN32 |
32 | | #include <windows.h> |
33 | | #elif __APPLE__ |
34 | | #include <mach-o/dyld.h> |
35 | | #elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) |
36 | | #include <unistd.h> // getpid |
37 | | #endif |
38 | | #include <sstream> |
39 | | |
40 | | using namespace LOG4CXX_NS; |
41 | | using namespace LOG4CXX_NS::helpers; |
42 | | |
43 | | |
44 | | LogString System::getProperty(const LogString& lkey) |
45 | 2.24k | { |
46 | 2.24k | if (lkey.empty()) |
47 | 0 | { |
48 | 0 | throw IllegalArgumentException(LOG4CXX_STR("key is empty")); |
49 | 0 | } |
50 | | |
51 | 2.24k | LogString rv; |
52 | | |
53 | 2.24k | if (lkey == LOG4CXX_STR("java.io.tmpdir")) |
54 | 0 | { |
55 | 0 | Pool p; |
56 | 0 | const char* dir = NULL; |
57 | 0 | apr_status_t stat = apr_temp_dir_get(&dir, p.getAPRPool()); |
58 | |
|
59 | 0 | if (stat == APR_SUCCESS) |
60 | 0 | { |
61 | 0 | Transcoder::decode(dir, rv); |
62 | 0 | } |
63 | |
|
64 | 0 | return rv; |
65 | 0 | } |
66 | | |
67 | 2.24k | if (lkey == LOG4CXX_STR("user.dir")) |
68 | 0 | { |
69 | 0 | Pool p; |
70 | 0 | char* dir = NULL; |
71 | 0 | apr_status_t stat = apr_filepath_get(&dir, APR_FILEPATH_NATIVE, |
72 | 0 | p.getAPRPool()); |
73 | |
|
74 | 0 | if (stat == APR_SUCCESS) |
75 | 0 | { |
76 | 0 | Transcoder::decode(dir, rv); |
77 | 0 | } |
78 | |
|
79 | 0 | return rv; |
80 | 0 | } |
81 | | |
82 | 2.24k | #if APR_HAS_USER |
83 | | |
84 | 2.24k | if (lkey == LOG4CXX_STR("user.home") || lkey == LOG4CXX_STR("user.name")) |
85 | 0 | { |
86 | 0 | Pool pool; |
87 | 0 | apr_uid_t userid; |
88 | 0 | apr_gid_t groupid; |
89 | 0 | apr_pool_t* p = pool.getAPRPool(); |
90 | 0 | apr_status_t stat = apr_uid_current(&userid, &groupid, p); |
91 | |
|
92 | 0 | if (stat == APR_SUCCESS) |
93 | 0 | { |
94 | 0 | char* username = NULL; |
95 | 0 | stat = apr_uid_name_get(&username, userid, p); |
96 | |
|
97 | 0 | if (stat == APR_SUCCESS) |
98 | 0 | { |
99 | 0 | if (lkey == LOG4CXX_STR("user.name")) |
100 | 0 | { |
101 | 0 | Transcoder::decode(username, rv); |
102 | 0 | } |
103 | 0 | else |
104 | 0 | { |
105 | 0 | char* dirname = NULL; |
106 | 0 | stat = apr_uid_homepath_get(&dirname, username, p); |
107 | |
|
108 | 0 | if (stat == APR_SUCCESS) |
109 | 0 | { |
110 | 0 | Transcoder::decode(dirname, rv); |
111 | 0 | } |
112 | 0 | } |
113 | 0 | } |
114 | 0 | } |
115 | |
|
116 | 0 | return rv; |
117 | 0 | } |
118 | | |
119 | 2.24k | #endif |
120 | | |
121 | 2.24k | LOG4CXX_ENCODE_CHAR(key, lkey); |
122 | 2.24k | Pool p; |
123 | 2.24k | char* value = NULL; |
124 | 2.24k | apr_status_t stat = apr_env_get(&value, key.c_str(), |
125 | 2.24k | p.getAPRPool()); |
126 | | |
127 | 2.24k | if (stat == APR_SUCCESS) |
128 | 0 | { |
129 | 0 | Transcoder::decode((const char*) value, rv); |
130 | 0 | } |
131 | | |
132 | 2.24k | return rv; |
133 | 2.24k | } |
134 | | |
135 | | void System::addProgramFilePathComponents(Properties& props) |
136 | 1 | { |
137 | | // Find the executable file name |
138 | 1 | static const int bufSize = 4096; |
139 | 1 | char buf[bufSize+1] = {0}, pathSepar = '/'; |
140 | | #if defined(_WIN32) |
141 | | if (0 == GetModuleFileName(NULL, buf, bufSize)) |
142 | | { |
143 | | Pool p; |
144 | | LogString lsErrorCode; |
145 | | StringHelper::toString((int)GetLastError(), p, lsErrorCode); |
146 | | LogLog::warn(LOG4CXX_STR("GetModuleFileName error ") + lsErrorCode); |
147 | | return; |
148 | | } |
149 | | pathSepar = '\\'; |
150 | | #elif defined(__APPLE__) |
151 | | uint32_t bufCount = bufSize; |
152 | | if (0 != _NSGetExecutablePath(buf, &bufCount)) |
153 | | { |
154 | | LogLog::warn(LOG4CXX_STR("_NSGetExecutablePath failed")); |
155 | | return; |
156 | | } |
157 | | #elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) |
158 | | int bufCount = 0; |
159 | 1 | std::ostringstream exeLink; |
160 | 1 | exeLink << "/proc/" << getpid() << "/exe"; |
161 | 1 | if ((bufCount = readlink(exeLink.str().c_str(), buf, bufSize)) <= 0) |
162 | 0 | { |
163 | 0 | LOG4CXX_DECODE_CHAR(lsExeLink, exeLink.str()); |
164 | 0 | LogLog::warn(LOG4CXX_STR("Failed to read ") + lsExeLink); |
165 | 0 | return; |
166 | 0 | } |
167 | 1 | if (bufSize < bufCount) |
168 | 0 | buf[bufSize] = 0; |
169 | 1 | else |
170 | 1 | buf[bufCount] = 0; |
171 | | #else |
172 | | LogLog::warn(LOG4CXX_STR("Unable to determine the name of the executable file on this system")); |
173 | | return; |
174 | | #endif |
175 | | |
176 | | // Add the path to the properties |
177 | 1 | std::string programFileName(buf); |
178 | 1 | if (programFileName.empty()) |
179 | 0 | { |
180 | 0 | LogLog::warn(LOG4CXX_STR("Current executable's file name is empty")); |
181 | 0 | return; |
182 | 0 | } |
183 | | |
184 | 1 | LOG4CXX_DECODE_CHAR(lsProgramFileName, programFileName); |
185 | 1 | LogString prefix{ LOG4CXX_STR("PROGRAM_FILE_PATH") }; |
186 | 1 | props.setProperty(prefix, lsProgramFileName); |
187 | | |
188 | 1 | #if LOG4CXX_HAS_FILESYSTEM_PATH |
189 | | // Add the path components to the properties |
190 | 1 | prefix += '.'; |
191 | 1 | FilesystemPath programPath(programFileName); |
192 | 1 | #if LOG4CXX_LOGCHAR_IS_WCHAR |
193 | 1 | auto root_name = programPath.root_name().wstring(); |
194 | 1 | props.setProperty(prefix + LOG4CXX_STR("ROOT_NAME"), root_name); |
195 | 1 | auto root_directory = programPath.root_directory().wstring(); |
196 | 1 | props.setProperty(LOG4CXX_STR("ROOT_DIRECTORY"),root_directory); |
197 | 1 | auto root_path = programPath.root_path().wstring(); |
198 | 1 | props.setProperty(prefix + LOG4CXX_STR("ROOT_PATH"), root_path); |
199 | 1 | auto relative_path = programPath.relative_path().wstring(); |
200 | 1 | props.setProperty(prefix + LOG4CXX_STR("RELATIVE_PATH"), relative_path); |
201 | 1 | auto parent_path = programPath.parent_path().wstring(); |
202 | 1 | props.setProperty(prefix + LOG4CXX_STR("PARENT_PATH"), parent_path); |
203 | 1 | auto filename = programPath.filename().wstring(); |
204 | 1 | props.setProperty(prefix + LOG4CXX_STR("FILENAME"), filename); |
205 | 1 | auto stem = programPath.stem().wstring(); |
206 | 1 | props.setProperty(prefix + LOG4CXX_STR("STEM"), stem); |
207 | 1 | auto extension = programPath.extension().wstring(); |
208 | 1 | props.setProperty(prefix + LOG4CXX_STR("EXTENSION"), extension); |
209 | | #else |
210 | | LOG4CXX_DECODE_CHAR(root_name, programPath.root_name().string()); |
211 | | props.setProperty(prefix + LOG4CXX_STR("ROOT_NAME"), root_name); |
212 | | LOG4CXX_DECODE_CHAR(root_directory, programPath.root_directory().string()); |
213 | | props.setProperty(LOG4CXX_STR("ROOT_DIRECTORY"),root_directory); |
214 | | LOG4CXX_DECODE_CHAR(root_path, programPath.root_path().string()); |
215 | | props.setProperty(prefix + LOG4CXX_STR("ROOT_PATH"), root_path); |
216 | | LOG4CXX_DECODE_CHAR(relative_path, programPath.relative_path().string()); |
217 | | props.setProperty(prefix + LOG4CXX_STR("RELATIVE_PATH"), relative_path); |
218 | | LOG4CXX_DECODE_CHAR(parent_path, programPath.parent_path().string()); |
219 | | props.setProperty(prefix + LOG4CXX_STR("PARENT_PATH"), parent_path); |
220 | | LOG4CXX_DECODE_CHAR(filename, programPath.filename().string()); |
221 | | props.setProperty(prefix + LOG4CXX_STR("FILENAME"), filename); |
222 | | LOG4CXX_DECODE_CHAR(stem, programPath.stem().string()); |
223 | | props.setProperty(prefix + LOG4CXX_STR("STEM"), stem); |
224 | | LOG4CXX_DECODE_CHAR(extension, programPath.extension().string()); |
225 | | props.setProperty(prefix + LOG4CXX_STR("EXTENSION"), extension); |
226 | | #endif |
227 | 1 | #endif // LOG4CXX_HAS_FILESYSTEM_PATH |
228 | 1 | } |