DDS  ver. 3.6
SysHelper.h
Go to the documentation of this file.
1 // Copyright 2014 GSI, Inc. All rights reserved.
2 //
3 // This file contains a number of helpers and wrappers of system calls.
4 //
5 #ifndef _DDS_SYSHELPER_H_
6 #define _DDS_SYSHELPER_H_
7 
8 // API
9 #include <fcntl.h>
10 #include <limits.h>
11 #include <netdb.h>
12 #include <pwd.h>
13 #include <sys/stat.h>
14 #include <sys/syscall.h>
15 #include <sys/types.h>
16 #include <unistd.h>
17 #ifdef __APPLE__
18 #include <sys/sysctl.h>
19 #endif
20 
21 // STD
22 #include <typeinfo>
23 // BOOST
24 #include <boost/asio.hpp>
25 
26 // HACK: On the SLC3 HOST_NAME_MAX is undefined
27 #ifndef HOST_NAME_MAX
28 #define HOST_NAME_MAX 64
29 #endif
30 
31 // Misc
32 #include "ErrorCode.h"
33 #include "MiscUtils.h"
34 #include "def.h"
35 
36 namespace dds::misc
37 {
42  inline void get_cuser_name(std::string* _RetVal)
43  {
44  if (!_RetVal)
45  return;
46 
47  passwd* pwd(getpwuid(geteuid()));
48  *_RetVal = pwd ? std::string(pwd->pw_name) : "";
49  }
56  inline void get_homedir(uid_t _uid, std::string* _RetVal)
57  {
58  if (!_RetVal)
59  return;
60 
61  passwd* pwd = getpwuid(_uid);
62  *_RetVal = pwd ? std::string(pwd->pw_dir) : "";
63  }
70  inline void get_homedir(const char* _UName, std::string* _RetVal)
71  {
72  if (!_RetVal)
73  return;
74 
75  passwd* pwd = getpwnam(_UName);
76  *_RetVal = pwd ? std::string(pwd->pw_dir) : "";
77  }
83  inline void get_cuser_homedir(std::string* _RetVal)
84  {
85  get_homedir(getuid(), _RetVal);
86  }
94  template <class _T>
95  inline void smart_path(_T* _Path)
96  {
97  if (nullptr == _Path || _Path->empty())
98  return;
99 
100  // Checking for "~/"
101  std::string path(*_Path);
102  trim_left(&path, ' ');
103  if ('~' == path[0])
104  {
105  std::string path(*_Path);
106  // ~/.../.../
107  if ('/' == path[1])
108  {
109  std::string sHome;
110  get_cuser_homedir(&sHome);
111  smart_append(&sHome, '/');
112 
113  path.erase(path.begin(), path.begin() + 2);
114  sHome += path;
115  path.swap(sHome);
116  _Path->swap(path);
117  }
118  else // ~user/.../.../
119  {
120  typename _T::size_type p = path.find(_T( "/" ));
121  if (_T::npos != p)
122  {
123  const std::string uname = path.substr(1, p - 1);
124  std::string home_dir;
125  get_homedir(uname.c_str(), &home_dir);
126  path.erase(path.begin(), path.begin() + p);
127  path = home_dir + path;
128  _Path->swap(path);
129  }
130  }
131  }
132 
133  typename _T::size_type p_begin = _Path->find(_T( "$" ));
134  if (_T::npos == p_begin)
135  {
136  // make the path to be the canonicalized absolute pathname
137  char resolved_path[PATH_MAX];
138  char* res = realpath(_Path->c_str(), resolved_path);
139  if (NULL != res)
140  {
141  // add trailing slash if needed, since realpath removes it
142  std::string::iterator it = _Path->end() - 1;
143  bool trailing_slash = (*it == '/');
144  *_Path = resolved_path;
145  if (trailing_slash)
146  smart_append(_Path, '/');
147  };
148 
149  return;
150  }
151 
152  ++p_begin; // Excluding '$' from the name
153 
154  typename _T::size_type p_end = _Path->find(_T( "/" ), p_begin);
155  if (_T::npos == p_end)
156  p_end = _Path->size();
157 
158  const _T env_var(_Path->substr(p_begin, p_end - p_begin));
159  // TODO: needs to be fixed to wide char: getenv
160  LPCTSTR szvar(getenv(env_var.c_str()));
161  if (!szvar)
162  return;
163  const _T var_val(szvar);
164  if (var_val.empty())
165  return;
166 
167  replace(_Path, _T( "$" ) + env_var, var_val);
168 
169  smart_path(_Path);
170  }
174  template <class _T>
175  inline _T smart_path(const _T& _Path)
176  {
177  _T tmp(_Path);
178  smart_path(&tmp);
179  return tmp;
180  }
185  inline void get_hostname(std::string* _RetVal)
186  {
187  if (!_RetVal)
188  return;
189 
190  *_RetVal = boost::asio::ip::host_name();
191  }
192 
197  inline unsigned long gettid()
198  {
199 #ifdef __APPLE__
200  union
201  {
202  pthread_t th;
203  unsigned long int i;
204  } v = {};
205  v.th = pthread_self();
206  return v.i;
207 #elif __linux
208  return syscall(__NR_gettid);
209 #else
210  return 0;
211 #endif
212  }
213 
250  class CMutex
251  {
252  public:
254  {
255  pthread_mutex_init(&m, 0);
256  }
257 
258  void Lock()
259  {
260  pthread_mutex_lock(&m);
261  }
262 
263  void Unlock()
264  {
265  pthread_mutex_unlock(&m);
266  }
267 
268  private:
269  pthread_mutex_t m;
270  };
275  class smart_mutex : public NONCopyable
276  {
277  public:
279  : m(_mutex)
280  {
281  m.Lock();
282  }
284  {
285  m.Unlock();
286  }
287 
288  private:
289  CMutex& m;
290  };
291 
300  extern "C" char* __cxa_demangle(const char* mangled, char* buf, size_t* len, int* status);
301  inline std::string demangle(const std::type_info& ti)
302  {
303  char* s = __cxa_demangle(ti.name(), 0, 0, 0);
304  std::string ret(s);
305  free(s);
306  return ret;
307  }
308 
309  inline void get_env(const std::string& _EnvVarName, std::string* _RetVal)
310  {
311  if (!_RetVal)
312  return;
313 
314  char* szBuf(getenv(_EnvVarName.c_str()));
315  if (szBuf)
316  _RetVal->assign(szBuf);
317  }
325  inline off_t file_size(const std::string& _FileName)
326  {
327  const int fd(::open(_FileName.c_str(), O_RDONLY));
328  if (-1 == fd)
329  throw system_error("Can't get file size of \"" + _FileName + "\"");
330 
331  struct stat fs;
332  const int ret(::fstat(fd, &fs));
333  close(fd);
334 
335  if (-1 == ret)
336  throw system_error("Can't get file size of \"" + _FileName + "\"");
337 
338  return fs.st_size;
339  }
345  inline bool file_exists(const std::string& _FileName)
346  {
347  try
348  {
349  file_size(_FileName);
350  return true;
351  }
352  catch (...)
353  {
354  return false;
355  }
356  }
362  inline size_t getNCores()
363  {
364  size_t numCPU(1);
365 #ifdef __APPLE__ // FreeBSD, MacOS X, NetBSD, OpenBSD, etc.
366  int mib[4];
367  size_t len = sizeof(numCPU);
368 
369  /* set the mib for hw.ncpu */
370  mib[0] = CTL_HW;
371  mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
372 
373  /* get the number of CPUs from the system */
374  sysctl(mib, 2, &numCPU, &len, NULL, 0);
375 
376  if (numCPU < 1)
377  {
378  mib[1] = HW_NCPU;
379  sysctl(mib, 2, &numCPU, &len, NULL, 0);
380 
381  if (numCPU < 1)
382  {
383  numCPU = 1;
384  }
385  }
386 #elif __linux // Linux, Solaris, & AIX (per comments)
387  numCPU = sysconf(_SC_NPROCESSORS_ONLN);
388 #endif
389  return numCPU;
390  }
391 }; // namespace dds::misc
392 #endif /*_DDS_SYSHELPER_H_*/
_T & trim_left(_T *_pString, const typename _T::value_type &_chWhat)
trims leading characters from the string.
Definition: MiscUtils.h:159
void get_cuser_name(std::string *_RetVal)
The function returns current user name.
Definition: SysHelper.h:42
void get_homedir(uid_t _uid, std::string *_RetVal)
The function returns home directory path of the given user.
Definition: SysHelper.h:56
bool file_exists(const std::string &_FileName)
Definition: SysHelper.h:345
~smart_mutex()
Definition: SysHelper.h:283
const char * LPCTSTR
Long Pointer to a Constant null-Terminated String.
Definition: def.h:66
CMutex()
Definition: SysHelper.h:253
void Unlock()
Definition: SysHelper.h:263
off_t file_size(const std::string &_FileName)
The function file_size() retrieves file size of a given file.
Definition: SysHelper.h:325
std::string demangle(const std::type_info &ti)
Definition: SysHelper.h:301
char * __cxa_demangle(const char *mangled, char *buf, size_t *len, int *status)
demangling C++ symbols.
size_t getNCores()
the function returns a number of available CPU cores
Definition: SysHelper.h:362
smart_mutex(CMutex &_mutex)
Definition: SysHelper.h:278
void Lock()
Definition: SysHelper.h:258
unsigned long gettid()
A system helper, which helps to get a Thread ID of the current thread.
Definition: SysHelper.h:197
#define _T(s)
Use TCHAR instead of char or wchar_t. It will be appropriately translated.
Definition: def.h:82
The system_error exception class retrieves a string, which represent the last error.
Definition: ErrorCode.h:76
_T & replace(_T *_pString, const _T &_what, const _T &_with)
finds elements in a string match a specified string and replaces it.
Definition: MiscUtils.h:188
void get_env(const std::string &_EnvVarName, std::string *_RetVal)
Definition: SysHelper.h:309
void smart_path(_T *_Path)
The function extends any environment variable found in the give path to its value.
Definition: SysHelper.h:95
Class which makes child to be non-copyable object.
Definition: MiscUtils.h:28
void get_cuser_homedir(std::string *_RetVal)
The function returns home directory path of the current user.
Definition: SysHelper.h:83
void get_hostname(std::string *_RetVal)
The function is used to access the host name (with FCDN) of the current processor.
Definition: SysHelper.h:185
A smart CMutex helper.
Definition: SysHelper.h:275
_T * smart_append(_T *_pString, const typename _T::value_type _ItemToAdd)
appends character _ItemToAdd to the string _pString if there is no such suffix on the end of _pString...
Definition: MiscUtils.h:125
A Mutex wrapper. Based on pthread calls.
Definition: SysHelper.h:250
Definition: BoostHelper.h:14