DDS  ver. 1.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 SYSHELPER_H_
6 #define 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 
24 // HACK: On the SLC3 HOST_NAME_MAX is undefined
25 #ifndef HOST_NAME_MAX
26 #define HOST_NAME_MAX 64
27 #endif
28 
29 // MiscCommon
30 #include "ErrorCode.h"
31 #include "MiscUtils.h"
32 #include "def.h"
33 
34 namespace MiscCommon
35 {
40  inline void get_cuser_name(std::string* _RetVal)
41  {
42  if (!_RetVal)
43  return;
44 
45  passwd* pwd(getpwuid(geteuid()));
46  *_RetVal = pwd ? std::string(pwd->pw_name) : "";
47  }
54  inline void get_homedir(uid_t _uid, std::string* _RetVal)
55  {
56  if (!_RetVal)
57  return;
58 
59  passwd* pwd = getpwuid(_uid);
60  *_RetVal = pwd ? std::string(pwd->pw_dir) : "";
61  }
68  inline void get_homedir(const char* _UName, std::string* _RetVal)
69  {
70  if (!_RetVal)
71  return;
72 
73  passwd* pwd = getpwnam(_UName);
74  *_RetVal = pwd ? std::string(pwd->pw_dir) : "";
75  }
81  inline void get_cuser_homedir(std::string* _RetVal)
82  {
83  get_homedir(getuid(), _RetVal);
84  }
92  template <class _T>
93  inline void smart_path(_T* _Path)
94  {
95  if (nullptr == _Path || _Path->empty())
96  return;
97 
98  // Checking for "~/"
99  std::string path(*_Path);
100  MiscCommon::trim_left(&path, ' ');
101  if ('~' == path[0])
102  {
103  std::string path(*_Path);
104  // ~/.../.../
105  if ('/' == path[1])
106  {
107  std::string sHome;
108  get_cuser_homedir(&sHome);
109  smart_append(&sHome, '/');
110 
111  path.erase(path.begin(), path.begin() + 2);
112  sHome += path;
113  path.swap(sHome);
114  _Path->swap(path);
115  }
116  else // ~user/.../.../
117  {
118  typename _T::size_type p = path.find(_T( "/" ));
119  if (_T::npos != p)
120  {
121  const std::string uname = path.substr(1, p - 1);
122  std::string home_dir;
123  get_homedir(uname.c_str(), &home_dir);
124  path.erase(path.begin(), path.begin() + p);
125  path = home_dir + path;
126  _Path->swap(path);
127  }
128  }
129  }
130 
131  typename _T::size_type p_begin = _Path->find(_T( "$" ));
132  if (_T::npos == p_begin)
133  {
134  // make the path to be the canonicalized absolute pathname
135  char resolved_path[PATH_MAX];
136  char* res = realpath(_Path->c_str(), resolved_path);
137  if (NULL != res)
138  {
139  // add trailing slash if needed, since realpath removes it
140  std::string::iterator it = _Path->end() - 1;
141  bool trailing_slash = (*it == '/');
142  *_Path = resolved_path;
143  if (trailing_slash)
144  smart_append(_Path, '/');
145  };
146 
147  return;
148  }
149 
150  ++p_begin; // Excluding '$' from the name
151 
152  typename _T::size_type p_end = _Path->find(_T( "/" ), p_begin);
153  if (_T::npos == p_end)
154  p_end = _Path->size();
155 
156  const _T env_var(_Path->substr(p_begin, p_end - p_begin));
157  // TODO: needs to be fixed to wide char: getenv
158  LPCTSTR szvar(getenv(env_var.c_str()));
159  if (!szvar)
160  return;
161  const _T var_val(szvar);
162  if (var_val.empty())
163  return;
164 
165  replace(_Path, _T( "$" ) + env_var, var_val);
166 
167  smart_path(_Path);
168  }
172  template <class _T>
173  inline _T smart_path(const _T& _Path)
174  {
175  _T tmp(_Path);
176  smart_path(&tmp);
177  return tmp;
178  }
183  inline void get_hostname(std::string* _RetVal)
184  {
185  if (!_RetVal)
186  return;
187 
188  // getting host name - which is without domain name
190  gethostname(&Buf[0], Buf.capacity());
191 
192  // getting host name with FCDN
193  hostent* h = gethostbyname(std::string(&Buf[0]).c_str());
194  if (!h)
195  return;
196 
197  *_RetVal = h->h_name;
198  }
199 
204  inline unsigned long gettid()
205  {
206 #ifdef __APPLE__
207  union {
208  pthread_t th;
209  unsigned long int i;
210  } v = {};
211  v.th = pthread_self();
212  return v.i;
213 #elif __linux
214  return syscall(__NR_gettid);
215 #else
216  return 0;
217 #endif
218  }
219 
256  class CMutex
257  {
258  public:
260  {
261  pthread_mutex_init(&m, 0);
262  }
263 
264  void Lock()
265  {
266  pthread_mutex_lock(&m);
267  }
268 
269  void Unlock()
270  {
271  pthread_mutex_unlock(&m);
272  }
273 
274  private:
275  pthread_mutex_t m;
276  };
281  class smart_mutex : public NONCopyable
282  {
283  public:
285  : m(_mutex)
286  {
287  m.Lock();
288  }
290  {
291  m.Unlock();
292  }
293 
294  private:
295  CMutex& m;
296  };
297 
306  extern "C" char* __cxa_demangle(const char* mangled, char* buf, size_t* len, int* status);
307  inline std::string demangle(const std::type_info& ti)
308  {
309  char* s = __cxa_demangle(ti.name(), 0, 0, 0);
310  std::string ret(s);
311  free(s);
312  return ret;
313  }
314 
315  inline void get_env(const std::string& _EnvVarName, std::string* _RetVal)
316  {
317  if (!_RetVal)
318  return;
319 
320  char* szBuf(getenv(_EnvVarName.c_str()));
321  if (szBuf)
322  _RetVal->assign(szBuf);
323  }
331  inline off_t file_size(const std::string& _FileName)
332  {
333  const int fd(::open(_FileName.c_str(), O_RDONLY));
334  if (-1 == fd)
335  throw system_error("Can't get file size of \"" + _FileName + "\"");
336 
337  struct stat fs;
338  const int ret(::fstat(fd, &fs));
339  close(fd);
340 
341  if (-1 == ret)
342  throw system_error("Can't get file size of \"" + _FileName + "\"");
343 
344  return fs.st_size;
345  }
351  inline bool file_exists(const std::string& _FileName)
352  {
353  try
354  {
355  file_size(_FileName);
356  return true;
357  }
358  catch (...)
359  {
360  return false;
361  }
362  }
368  inline size_t getNCores()
369  {
370  size_t numCPU(1);
371 #ifdef __APPLE__ // FreeBSD, MacOS X, NetBSD, OpenBSD, etc.
372  int mib[4];
373  size_t len = sizeof(numCPU);
374 
375  /* set the mib for hw.ncpu */
376  mib[0] = CTL_HW;
377  mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
378 
379  /* get the number of CPUs from the system */
380  sysctl(mib, 2, &numCPU, &len, NULL, 0);
381 
382  if (numCPU < 1)
383  {
384  mib[1] = HW_NCPU;
385  sysctl(mib, 2, &numCPU, &len, NULL, 0);
386 
387  if (numCPU < 1)
388  {
389  numCPU = 1;
390  }
391  }
392 #elif __linux // Linux, Solaris, & AIX (per comments)
393  numCPU = sysconf(_SC_NPROCESSORS_ONLN);
394 #endif
395  return numCPU;
396  }
397 };
398 #endif /*SYSHELPER_H_*/
_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:121
_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:184
_T & trim_left(_T *_pString, const typename _T::value_type &_chWhat)
trims leading characters from the string.
Definition: MiscUtils.h:155
void get_cuser_name(std::string *_RetVal)
The function returns current user name.
Definition: SysHelper.h:40
CMutex()
Definition: SysHelper.h:259
~smart_mutex()
Definition: SysHelper.h:289
std::string demangle(const std::type_info &ti)
Definition: SysHelper.h:307
char * __cxa_demangle(const char *mangled, char *buf, size_t *len, int *status)
demangling C++ symbols.
smart_mutex(CMutex &_mutex)
Definition: SysHelper.h:284
The system_error exception class retrieves a string, which represent the last error.
Definition: ErrorCode.h:77
void Unlock()
Definition: SysHelper.h:269
A smart CMutex helper.
Definition: SysHelper.h:281
off_t file_size(const std::string &_FileName)
The function file_size() retrieves file size of a given file.
Definition: SysHelper.h:331
Class which makes child to be non-copyable object.
Definition: MiscUtils.h:24
bool file_exists(const std::string &_FileName)
Definition: SysHelper.h:351
void get_homedir(uid_t _uid, std::string *_RetVal)
The function returns home directory path of the given user.
Definition: SysHelper.h:54
void get_env(const std::string &_EnvVarName, std::string *_RetVal)
Definition: SysHelper.h:315
unsigned long gettid()
A system helper, which helps to get a Thread ID of the current thread.
Definition: SysHelper.h:204
std::vector< char > CHARVector_t
An STL vector of char(s).
Definition: def.h:121
#define HOST_NAME_MAX
Definition: SysHelper.h:26
void get_hostname(std::string *_RetVal)
The function is used to access the host name (with FCDN) of the current processor.
Definition: SysHelper.h:183
void get_cuser_homedir(std::string *_RetVal)
The function returns home directory path of the current user.
Definition: SysHelper.h:81
#define _T(s)
Use TCHAR instead of char or wchar_t. It will be appropriately translated.
Definition: def.h:85
size_t getNCores()
the function returns a number of available CPU cores
Definition: SysHelper.h:368
void smart_path(_T *_Path)
The function extends any environment variable found in the give path to its value.
Definition: SysHelper.h:93
const char * LPCTSTR
Long Pointer to a Constant null-Terminated String.
Definition: def.h:69
A Mutex wrapper. Based on pthread calls.
Definition: SysHelper.h:256
void Lock()
Definition: SysHelper.h:264
Miscellaneous functions and helpers are located here.
Definition: BOOST_FILESYSTEM.h:21