Coverage Report

Created: 2025-08-26 06:48

/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
}