#ifndef __JSYSTEMTOOLKIT__ #define __JSYSTEMTOOLKIT__ #include #include #include #include #include #include "JLang/JException.hh" #include "JSystem/JShell.hh" #include "JSystem/JSysinfo.hh" /** * \file * System auxiliaries. * \author mdejong */ /** * Auxiliary classes and methods for operating system calls. */ namespace JSYSTEM {} namespace JPP { using namespace JSYSTEM; } namespace JSYSTEM { using JLANG::JSystemException; /** * Shell names. */ static const char* const SH = "sh"; static const char* const ZSH = "zsh"; static const char* const KSH = "ksh"; static const char* const BASH = "bash"; static const char* const CSH = "csh"; static const char* const TCSH = "tcsh"; static const std::string SPECIAL_CHARACTERS = "\"' <>[](){};$#"; /** * Get memory usage in percent of given process identifier. * * \param shell shell interface * \param pid process identifier * \return memory usage [%] */ inline float getMemoryUsage(JShell& shell, const pid_t pid) { using namespace std; float value = 0.0; shell << "ps -o %mem= -p " << pid << endl; if (shell.get(value)) return value; else THROW(JSystemException, "No process data for PID " << pid); } /** * Get memory usage in percent of this process. * * \param shell shell interface * \return memory usage [%] */ inline float getMemoryUsage(JShell& shell) { return getMemoryUsage(shell, getpid()); } /** * Get memory usage in percent of this process. * * \return memory usage [%] */ inline float getMemoryUsage() { return getMemoryUsage(JShell::getInstance(), getpid()); } /** * Get cpu usage in percent of given process identifier. * * \param shell shell interface * \param pid process identifier * \return cpu usage [%] */ inline float getCpuUsage(JShell& shell, const pid_t pid) { using namespace std; float value = 0.0; shell << "ps -o %cpu= -p " << pid << endl; if (shell.get(value)) return value; else THROW(JSystemException, "No process data for PID " << pid); } /** * Get cpu usage in percent of this process. * * \param shell shell interface * \return cpu usage [%] */ inline float getCpuUsage(JShell& shell) { return getCpuUsage(shell, getpid()); } /** * Get cpu usage in percent of this process. * * \return cpu usage [%] */ inline float getCpuUsage() { return getCpuUsage(JShell::getInstance(), getpid()); } /** * Get process identifier. * * \param shell shell interface * \param process process name * \return process identifier */ inline pid_t getPID(JShell& shell, const char* process) { using namespace std; pid_t pid = -1; shell << "ps -o pid= -C " << process << endl; if (shell.get(pid)) return pid; else THROW(JSystemException, "No process " << process); } /** * Get process identifier. * * \param process process name * \return process identifier */ inline pid_t getPID(const char* process) { return getPID(JShell::getInstance(), process); } /** * Get parent process identifier. * * \param shell shell interface * \param pid process identifier * \return parent identifier */ inline pid_t getParentID(JShell& shell, pid_t pid) { using namespace std; shell << "ps -o ppid= -p " << pid << endl; if (shell.get(pid)) return pid; else THROW(JSystemException, "No parent identifier " << pid); } /** * Get parent process identifier. * * \param pid process identifier * \return parent identifier */ inline pid_t getParentID(const pid_t pid) { return getParentID(JShell::getInstance(), getpid()); } /** * Get shell name. * * \param shell shell interface * \return shell name */ inline std::string getShell(JShell& shell) { using namespace std; static string value = ""; if (value == "") { pid_t pid = getppid(); shell << "ps -o ppid= -o args= -p " << pid << endl; if (shell >> pid >> value) { shell.flush(); if (!value.empty() && value[0] == '-') { value = value.substr(1); } } else { static_cast(shell).clear(); shell.flush(); THROW(JSystemException, "No shell"); } } return value; } /** * Get shell name of this process. * * \return shell name */ inline std::string getShell() { return getShell(JShell::getInstance()); } /** * Get RAM of this CPU. * * \return number of bytes */ inline unsigned long long int getRAM() { const JSysinfo info; return info.getTotalRAM(); } /** * Get process path. * * \param shell shell interface * \param process process name * \return path */ inline const std::string which(JShell& shell, const char* process) { using namespace std; string buffer; shell << "which " << process << endl; shell.getline(buffer); shell.flush(); return buffer; } /** * Get process path. * * \param process process name * \return path */ inline const std::string which(const char* process) { return which(JShell::getInstance(), process); } /** * Auxiliary data structure to list files in directory. */ struct ls : public std::vector { /** * Constructor. * * \param dir directory */ ls(const std::string& dir) { DIR* top = opendir(dir.c_str()); if (top != NULL) { for (dirent* i; (i = readdir(top)) != NULL; ) { this->push_back(i->d_name); } closedir(top); } } }; /** * Print method. * * \param message message */ inline void gprint(const std::string& message) { using namespace std; istringstream is(message); for (string buffer; getline(is, buffer); ) { if (!buffer.empty()) { for (string::size_type i = 0; i != buffer.size(); ++i) { if (SPECIAL_CHARACTERS.find(buffer[i]) != string::npos) { buffer.insert(i++, "\\"); } } cout << "echo " << buffer << ";" << endl; } } } /** * Exit method. * * \param status exit status * \param message optional message */ inline int gexit(int status, const std::string& message = "") { using namespace std; gprint(message); cout << "exit " << status << ";" << endl; return status; } /** * Set environment variable. * * This method prints the shell command to set the variable with the given name to the specified value. * * \param name variable name * \param value variable value */ inline void set_variable(const std::string& name, const std::string& value) { using namespace std; using namespace JSYSTEM; static const string shell = getShell(); string buffer(value); if (buffer.find(' ') != string::npos) { buffer = "\"" + buffer + "\""; } if (shell.find(ZSH) != string::npos || shell.find(KSH) != string::npos || shell.find(BASH) != string::npos) { cout << "export " << name << "=" << buffer << ";" << endl; } else if (shell.find(CSH) != string::npos || shell.find(TCSH) != string::npos) { cout << "setenv " << name << " " << buffer << ";" << endl; } else { THROW(JSystemException, "unknown shell " << shell); } } }; #endif