1/*
2 * Copyright (C) 2020-2022 The opuntiaOS Project Authors.
3 * + Contributed by Nikita Melekhin <nimelehin@gmail.com>
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include <cstring>
10#include <iostream>
11#include <libfoundation/Logger.h>
12#include <libfoundation/ProcessInfo.h>
13#include <libfoundation/json/Parser.h>
14#include <memory>
15#include <unistd.h>
16
17namespace LFoundation {
18
19ProcessInfo* s_LFoundation_ProcessInfo_the = nullptr;
20
21ProcessInfo::ProcessInfo(int argc, char** argv)
22{
23 s_LFoundation_ProcessInfo_the = this;
24
25 // Parse argv[0] to get a process name.
26 int process_name_start = 0;
27 for (int i = 0; i < strlen(argv[0]) - 1; i++) {
28 if (argv[0][i] == '/') {
29 process_name_start = i + 1;
30 }
31 }
32 m_process_name = std::string(&argv[0][process_name_start]);
33
34 for (int i = 1; i < argc; i++) {
35 m_args.push_back(std::string(argv[i]));
36 }
37
38 parse_info_file();
39}
40
41int ProcessInfo::processor_count()
42{
43 // TODO: Temp solution. Until sysctl.
44 if (m_processor_count < 0) {
45 m_processor_count = 0;
46 char buf[256];
47 int fd_proc_stat = open("/proc/stat", O_RDONLY);
48 int offset = 0;
49 int rd = 1;
50 read(fd_proc_stat, buf, sizeof(buf));
51 while (rd > 0) {
52 int num, user_time, system_time, idle_time;
53 rd = sscanf(buf + offset, "cpu%d %d 0 %d %d\n", &num, &user_time, &system_time, &idle_time);
54 offset += rd;
55 if (rd > 0) {
56 m_processor_count++;
57 }
58 }
59 close(fd_proc_stat);
60 }
61 return m_processor_count;
62}
63
64void ProcessInfo::parse_info_file()
65{
66 char execpath[256];
67 char infofile[256];
68 char bundleid[256];
69
70 int fd = open("/proc/self/exe", O_RDONLY);
71 int rd = read(fd, execpath, sizeof(execpath));
72 close(fd);
73 int start = 0;
74 for (int i = rd - 1; i >= 0; i--) {
75 if (execpath[i] == '/') {
76 start = i + 1;
77 break;
78 }
79 }
80 memcpy(&execpath[start], "info.json", sizeof("info.json") + 1);
81
82 auto json_parser = LFoundation::Json::Parser(execpath);
83 LFoundation::Json::Object* jobj_root = json_parser.object();
84 if (jobj_root->invalid()) {
85 return;
86 }
87
88 auto* jdict_root = jobj_root->cast_to<LFoundation::Json::DictObject>();
89 m_bundle_id = jdict_root->data()["bundle_id"]->cast_to<LFoundation::Json::StringObject>()->data();
90}
91
92} // namespace LFoundation