linux_systemutil.cpp
Go to the documentation of this file.
1/**
2 * @author: Daniel Fuchs
3 * @contact: fuxeysolutions@gmail.com
4 *
5 * distributed under the MIT License (MIT).
6 * Copyright (c) Daniel Fuchs
7 *
8 */
10
11#include <cinttypes>
12#include <csignal>
13#include <cstdio>
14#include <cstdlib>
15#include <cstring>
16#include <fstream>
17#include <iostream>
18#include <thread>
19
20#include <dirent.h>
21#include <netinet/in.h>
22#include <pwd.h>
23#include <sys/stat.h>
24#include <sys/statvfs.h>
25#include <sys/types.h>
26#include <unistd.h>
27
28int64_t
29linuxUtil::getTemperature(const std::string& thermalZone)
30{
31 std::ifstream temperatureFile;
32 const std::string parsePath = "/sys/class/thermal/" + thermalZone + "/temp";
33 temperatureFile.open(parsePath);
34
35 int64_t temperature;
36 std::string line;
37 while (std::getline(temperatureFile, line))
38 {
39 auto unused = scanf(line.c_str(), "%ld", &temperature);
40 (void)unused;
41 }
42 temperatureFile.close();
43 return temperature;
44}
45
46int
47linuxUtil::getProcIdByName(const std::string& procName)
48{
49 int pid = -1;
50 auto dp = opendir("/proc");
51 if (dp != nullptr)
52 {
53 struct dirent* dirp;
54 while (pid < 0 && (dirp = readdir(dp)))
55 {
56 int id = atoi(dirp->d_name);
57 if (id > 0)
58 {
59 std::string cmdPath{"/proc/"};
60 cmdPath.append(dirp->d_name);
61 cmdPath.append("/cmdline");
62 std::ifstream cmdFile(cmdPath.c_str());
63 std::string cmdLine;
64 getline(cmdFile, cmdLine);
65 if (!cmdLine.empty())
66 {
67 size_t pos = cmdLine.find('\0');
68 if (pos != std::string::npos)
69 cmdLine = cmdLine.substr(0, pos);
70 pos = cmdLine.rfind('/');
71 if (pos != std::string::npos)
72 cmdLine = cmdLine.substr(pos + 1);
73 if (strcmp(procName.c_str(), cmdLine.c_str()) == 0)
74 {
75 pid = id;
76 }
77 }
78 }
79 }
80 }
81 closedir(dp);
82 return pid;
83}
84
85int
86linuxUtil::killProcessById(int pid, const std::string& procName)
87{
88 if (pid == -1)
89 {
90 throw std::runtime_error("Nothing to Kill, no Process " + procName + " PID " +
91 std::to_string(pid));
92 }
93 int ret = kill(pid, 9);
94 if (ret == -1)
95 {
96 throw std::runtime_error("killing " + procName + " was not successful!");
97 }
98 return ret;
99}
100
101uint64_t
103{
104 std::ifstream upTimeFile;
105 upTimeFile.open("/proc/uptime");
106
107 if (!upTimeFile.is_open())
108 {
109 return 0;
110 }
111
112 uint64_t beforeBootTime;
113 uint64_t sysUptime = 0;
114 std::string line;
115 while (std::getline(upTimeFile, line))
116 {
117 sscanf(line.c_str(), "%" PRIu64 "%" PRIu64, &sysUptime, &beforeBootTime);
118 }
119 upTimeFile.close();
120 return sysUptime;
121}
122
123bool
125{
126 pid_t pid = fork();
127 if (pid < 0)
128 {
129 return false;
130 }
131
132 if (pid > 0)
133 std::exit(EXIT_SUCCESS);
134
135 if (setsid() < 0)
136 std::exit(EXIT_FAILURE);
137
138 //TODO: Implement a working signal handler */
139 std::signal(SIGCHLD, SIG_IGN);
140 std::signal(SIGHUP, SIG_IGN);
141
142 pid = fork();
143 if (pid < 0)
144 std::exit(EXIT_FAILURE);
145
146 if (pid > 0)
147 std::exit(EXIT_SUCCESS);
148
149 umask(0);
150 auto retval = chdir("/test");
151 if (retval < 0)
152 {
153 return false;
154 }
155
156 for (int x = sysconf(_SC_OPEN_MAX); x >= 0; x--)
157 {
158 close(x);
159 }
160 return true;
161}
162
163uint64_t
164linuxUtil::getFreeDiskSpace(std::string absoluteFilePath)
165{
166 struct statvfs buf;
167
168 if (!statvfs(absoluteFilePath.c_str(), &buf))
169 {
170 uint64_t blksize, blocks, freeblks, disk_size, used, free;
171 std::cout << "blksize :" << buf.f_bsize << std::endl;
172 std::cout << "blocks : " << buf.f_blocks;
173 std::cout << "bfree : " << buf.f_bfree;
174 std::cout << "bavail: " << buf.f_bavail;
175 std::cout << "f_frsize: " << buf.f_frsize;
176 blksize = buf.f_bsize;
177 blocks = buf.f_blocks;
178 freeblks = buf.f_bfree;
179 disk_size = blocks * blksize;
180 free = freeblks * blksize;
181 used = disk_size - free;
182
183 std::cout << "disk " << absoluteFilePath << " disksize: " << disk_size << " free: " << free
184 << " used: " << used << std::endl;
185 return free;
186 }
187 else
188 {
189 return 0;
190 }
191 return 0;
192}
193
194uint64_t
196{
197 struct statvfs stat;
198 struct passwd* pw = getpwuid(getuid());
199 if (nullptr != pw && 0 == statvfs(pw->pw_dir, &stat))
200 {
201 std::cout << "path " << pw->pw_dir << std::endl;
202 uint64_t freeBytes = stat.f_bavail * stat.f_frsize;
203 return freeBytes;
204 }
205 return 0ULL;
206}
207
208std::string
210{
211 std::ifstream versionFile;
212 versionFile.open("/proc/version_signature");
213
214 if (!versionFile.is_open())
215 {
216 return std::string();
217 }
218 std::string line;
219 std::getline(versionFile, line);
220
221 versionFile.close();
222 return line;
223}
224
225std::string
227{
228 std::ifstream versionFile;
229 versionFile.open("/proc/version");
230
231 if (!versionFile.is_open())
232 {
233 return std::string();
234 }
235 std::string line;
236 std::getline(versionFile, line);
237
238 versionFile.close();
239 return line;
240}
241
242bool
243linuxUtil::isDeviceOnline(std::string address)
244{
245 const std::string processPrefix = {"ping -c 1 -w 1 "};
246 const std::string processPostfix = {" 2>&1"};
247 auto fd = popen((processPrefix + address + processPostfix).c_str(), "r");
248 std::this_thread::sleep_for(std::chrono::seconds(2));
249 if (fd == nullptr)
250 {
251 return false;
252 }
253 char buff[1000];
254 char* ptr = buff;
255 size_t sz = sizeof(buff);
256 while (getline(&ptr, &sz, fd) != -1)
257 {
258 std::string line(buff);
259 if (line.find(" 1 received") != std::string::npos)
260 {
261 pclose(fd);
262 return true;
263 }
264 if (line.find("100% packet loss") != std::string::npos)
265 {
266 pclose(fd);
267 return false;
268 }
269 }
270 return false;
271}
272
273uint32_t
275{
276 uint32_t Threads = 0;
277 std::ifstream memoryFile;
278 memoryFile.open("/proc/self/status");
279 std::string line;
280 while (std::getline(memoryFile, line))
281 {
282 sscanf(line.c_str(), "Threads: %u", &Threads);
283 }
284 return Threads;
285}
286
287uint32_t
289{
290 uint32_t Threads = 0;
291 std::ifstream memoryFile;
292 memoryFile.open("/proc/self/" + std::to_string(Pid));
293 std::string line;
294 while (std::getline(memoryFile, line))
295 {
296 sscanf(line.c_str(), "Threads: %u", &Threads);
297 }
298 return Threads;
299}
300
301std::string
302linuxUtil::getIFaceMacAddress(std::string deviceName)
303{
304 const std::string sysClassPath = "/sys/class/net/";
305
306 std::ifstream IFaceFile;
307 IFaceFile.open(sysClassPath + deviceName + "/address");
308 std::string line;
309 std::getline(IFaceFile, line);
310 return line;
311}
static int killProcessById(int pid, const std::string &procName)
static std::string getOsVersionString(void)
static uint32_t getNumOfThreadsByPID(int Pid)
static std::string getIFaceMacAddress(std::string deviceName)
static bool isDeviceOnline(std::string address)
static int getProcIdByName(const std::string &procName)
static int64_t getTemperature(const std::string &thermalZone="thermal_zone0")
static uint64_t getSysUpTime()
static bool startAppAsDaemon()
static uint64_t userAvailableFreeSpace()
static uint64_t getFreeDiskSpace(std::string absoluteFilePath)
static uint32_t getNumOfThreadsByThisProcess()
static std::string getOSVersion_Signature(void)
This file offers overloads of toIce() and fromIce() functions for STL container types.