@gjsify/os 0.0.4 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -1
- package/lib/esm/constants.js +15 -0
- package/lib/esm/darwin.js +50 -14
- package/lib/esm/index.js +167 -25
- package/lib/esm/linux.js +106 -21
- package/lib/types/constants.d.ts +135 -0
- package/lib/types/createSubnet.d.ts +5 -0
- package/lib/types/darwin.d.ts +16 -0
- package/lib/types/index.d.ts +204 -0
- package/lib/types/linux.d.ts +17 -0
- package/lib/types/win32.d.ts +0 -0
- package/package.json +16 -17
- package/src/constants.ts +17 -1
- package/src/createSubnet.ts +3 -0
- package/src/darwin.ts +83 -23
- package/src/index.spec.ts +388 -4
- package/src/index.ts +170 -15
- package/src/linux.ts +136 -26
- package/src/win32.ts +3 -0
- package/tsconfig.json +23 -10
- package/tsconfig.tsbuildinfo +1 -0
- package/lib/cjs/constants.js +0 -122
- package/lib/cjs/createSubnet.js +0 -17
- package/lib/cjs/darwin.js +0 -115
- package/lib/cjs/index.js +0 -92
- package/lib/cjs/linux.js +0 -92
- package/lib/cjs/win32.js +0 -1
- package/test.gjs.mjs +0 -34685
- package/test.gjs.mjs.meta.json +0 -1
- package/test.node.mjs +0 -307
- package/tsconfig.types.json +0 -8
package/README.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
1
|
# @gjsify/os
|
|
2
2
|
|
|
3
|
-
Node.js os module
|
|
3
|
+
GJS implementation of the Node.js `os` module using GLib. Provides homedir, hostname, cpus, and more.
|
|
4
|
+
|
|
5
|
+
Part of the [gjsify](https://github.com/gjsify/gjsify) project — Node.js and Web APIs for GJS (GNOME JavaScript).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @gjsify/os
|
|
11
|
+
# or
|
|
12
|
+
yarn add @gjsify/os
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { homedir, hostname, platform, cpus } from '@gjsify/os';
|
|
19
|
+
|
|
20
|
+
console.log(homedir());
|
|
21
|
+
console.log(hostname());
|
|
22
|
+
console.log(platform());
|
|
23
|
+
console.log(cpus().length);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## License
|
|
27
|
+
|
|
28
|
+
MIT
|
package/lib/esm/constants.js
CHANGED
|
@@ -115,6 +115,21 @@ var constants_default = {
|
|
|
115
115
|
"SIGPOLL": 29,
|
|
116
116
|
"SIGPWR": 30,
|
|
117
117
|
"SIGSYS": 31
|
|
118
|
+
},
|
|
119
|
+
"priority": {
|
|
120
|
+
"PRIORITY_LOW": 19,
|
|
121
|
+
"PRIORITY_BELOW_NORMAL": 10,
|
|
122
|
+
"PRIORITY_NORMAL": 0,
|
|
123
|
+
"PRIORITY_ABOVE_NORMAL": -7,
|
|
124
|
+
"PRIORITY_HIGH": -14,
|
|
125
|
+
"PRIORITY_HIGHEST": -20
|
|
126
|
+
},
|
|
127
|
+
"dlopen": {
|
|
128
|
+
"RTLD_LAZY": 1,
|
|
129
|
+
"RTLD_NOW": 2,
|
|
130
|
+
"RTLD_GLOBAL": 256,
|
|
131
|
+
"RTLD_LOCAL": 0,
|
|
132
|
+
"RTLD_DEEPBIND": 8
|
|
118
133
|
}
|
|
119
134
|
};
|
|
120
135
|
export {
|
package/lib/esm/darwin.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { createSubnet } from "./createSubnet.js";
|
|
2
2
|
import { cli } from "@gjsify/utils";
|
|
3
|
-
const EOL = /\r\n|\n/;
|
|
4
3
|
const NOMAC = "00:00:00:00:00:00";
|
|
5
4
|
const getIPv6Subnet = createSubnet(128, 16, 16, ":");
|
|
6
5
|
const parseInterfaces = function(info) {
|
|
7
6
|
info = info.trim();
|
|
8
|
-
if (info.length < 1 || !/\binet\b/.test(info))
|
|
9
|
-
return;
|
|
7
|
+
if (info.length < 1 || !/\binet\b/.test(info)) return;
|
|
10
8
|
const lines = info.split("\n");
|
|
11
9
|
const iface = [];
|
|
12
10
|
const length = lines.length;
|
|
@@ -60,7 +58,27 @@ const cpus = () => {
|
|
|
60
58
|
return cpus2;
|
|
61
59
|
};
|
|
62
60
|
const endianness = () => "LE";
|
|
63
|
-
const freemem = () =>
|
|
61
|
+
const freemem = () => {
|
|
62
|
+
try {
|
|
63
|
+
const vmstat = cli("vm_stat");
|
|
64
|
+
const pageSizeMatch = /page size of (\d+) bytes/.exec(vmstat);
|
|
65
|
+
const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 16384;
|
|
66
|
+
let freePages = 0;
|
|
67
|
+
const freeMatch = /Pages free:\s+(\d+)/.exec(vmstat);
|
|
68
|
+
if (freeMatch) freePages += parseInt(freeMatch[1], 10);
|
|
69
|
+
const specMatch = /Pages speculative:\s+(\d+)/.exec(vmstat);
|
|
70
|
+
if (specMatch) freePages += parseInt(specMatch[1], 10);
|
|
71
|
+
const purgeMatch = /Pages purgeable:\s+(\d+)/.exec(vmstat);
|
|
72
|
+
if (purgeMatch) freePages += parseInt(purgeMatch[1], 10);
|
|
73
|
+
if (freePages > 0) return freePages * pageSize;
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
return parseFloat(cli("sysctl -n hw.memsize")) - parseFloat(cli("sysctl -n hw.physmem"));
|
|
78
|
+
} catch {
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
64
82
|
const loadavg = () => /load\s+averages:\s+(\d+(?:\.\d+))\s+(\d+(?:\.\d+))\s+(\d+(?:\.\d+))/.test(
|
|
65
83
|
cli("uptime")
|
|
66
84
|
) && [
|
|
@@ -71,7 +89,7 @@ const loadavg = () => /load\s+averages:\s+(\d+(?:\.\d+))\s+(\d+(?:\.\d+))\s+(\d+
|
|
|
71
89
|
const networkInterfaces = () => {
|
|
72
90
|
const ifaces = {};
|
|
73
91
|
const groups = [];
|
|
74
|
-
const lines = cli("ifconfig").split(
|
|
92
|
+
const lines = cli("ifconfig").split(/\r\n|\n/);
|
|
75
93
|
const length = lines.length;
|
|
76
94
|
for (let group = [], re = /^\S+?:/, i = 0; i < length; i++) {
|
|
77
95
|
if (re.test(lines[i])) {
|
|
@@ -81,28 +99,46 @@ const networkInterfaces = () => {
|
|
|
81
99
|
}
|
|
82
100
|
--i;
|
|
83
101
|
}
|
|
84
|
-
groups.push(group.join(
|
|
102
|
+
groups.push(group.join("\n"));
|
|
85
103
|
}
|
|
86
104
|
groups.forEach(parseInterfaces, ifaces);
|
|
87
105
|
return ifaces;
|
|
88
106
|
};
|
|
89
107
|
const totalmem = () => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
108
|
+
try {
|
|
109
|
+
return parseFloat(cli("sysctl -n hw.memsize"));
|
|
110
|
+
} catch {
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
93
113
|
};
|
|
94
114
|
const uptime = () => {
|
|
95
|
-
|
|
96
|
-
|
|
115
|
+
try {
|
|
116
|
+
const boottime = cli("sysctl -n kern.boottime");
|
|
117
|
+
const secMatch = /sec\s*=\s*(\d+)/.exec(boottime);
|
|
118
|
+
if (secMatch) {
|
|
119
|
+
const bootSec = parseInt(secMatch[1], 10);
|
|
120
|
+
const nowSec = Math.floor(Date.now() / 1e3);
|
|
121
|
+
return nowSec - bootSec;
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
}
|
|
125
|
+
const output = cli("uptime");
|
|
126
|
+
const up = /up\s+([^,]+)?,/.test(output) && RegExp.$1;
|
|
97
127
|
switch (true) {
|
|
98
128
|
case /^(\d+):(\d+)$/.test(up):
|
|
99
129
|
return (parseInt(RegExp.$1, 10) * 60 + parseInt(RegExp.$2, 10)) * 60;
|
|
100
130
|
case /^(\d+)\s+mins?$/.test(up):
|
|
101
131
|
return parseInt(RegExp.$1, 10) * 60;
|
|
102
|
-
case /^(\d+)\s+days?$/.test(up):
|
|
103
|
-
|
|
132
|
+
case /^(\d+)\s+days?$/.test(up): {
|
|
133
|
+
const days = parseInt(RegExp.$1, 10) * 86400;
|
|
134
|
+
const timeMatch = /days?,\s+(\d+):(\d+)/.exec(output);
|
|
135
|
+
if (timeMatch) {
|
|
136
|
+
return days + (parseInt(timeMatch[1], 10) * 60 + parseInt(timeMatch[2], 10)) * 60;
|
|
137
|
+
}
|
|
138
|
+
return days;
|
|
139
|
+
}
|
|
104
140
|
}
|
|
105
|
-
return
|
|
141
|
+
return 0;
|
|
106
142
|
};
|
|
107
143
|
export {
|
|
108
144
|
cpus,
|
package/lib/esm/index.js
CHANGED
|
@@ -1,92 +1,234 @@
|
|
|
1
|
-
import { cli, getPathSeparator
|
|
1
|
+
import { cli, getPathSeparator } from "@gjsify/utils";
|
|
2
|
+
import Gio from "@girs/gio-2.0";
|
|
3
|
+
let _os = "";
|
|
4
|
+
const getOs = () => {
|
|
5
|
+
if (_os) return _os;
|
|
6
|
+
const os = cli("uname -o").trim();
|
|
7
|
+
if (/\bDarwin\b/i.test(os)) {
|
|
8
|
+
_os = "darwin";
|
|
9
|
+
return _os;
|
|
10
|
+
}
|
|
11
|
+
if (/\bLinux\b/i.test(os)) {
|
|
12
|
+
_os = "linux";
|
|
13
|
+
return _os;
|
|
14
|
+
}
|
|
15
|
+
_os = "win32";
|
|
16
|
+
return _os;
|
|
17
|
+
};
|
|
18
|
+
let _pid = 0;
|
|
19
|
+
const getPid = () => {
|
|
20
|
+
if (!_pid) _pid = new Gio.Credentials().get_unix_pid();
|
|
21
|
+
return _pid;
|
|
22
|
+
};
|
|
2
23
|
import * as linux from "./linux.js";
|
|
3
24
|
import * as darwin from "./darwin.js";
|
|
4
25
|
import GLib from "@girs/glib-2.0";
|
|
5
26
|
import constants from "./constants.js";
|
|
6
27
|
const EOL = getPathSeparator() === "/" ? "\n" : "\r\n";
|
|
28
|
+
const devNull = getPathSeparator() === "/" ? "/dev/null" : "\\\\.\\nul";
|
|
7
29
|
const homedir = () => GLib.get_home_dir();
|
|
8
30
|
const hostname = () => GLib.get_host_name();
|
|
9
|
-
const release = () => cli("uname -r");
|
|
31
|
+
const release = () => cli("uname -r").trim();
|
|
10
32
|
const tmpdir = () => GLib.get_tmp_dir();
|
|
11
|
-
const type = () => cli("uname");
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
33
|
+
const type = () => cli("uname").trim();
|
|
34
|
+
const platform = () => cli("uname -s").trim().toLowerCase();
|
|
35
|
+
const arch = () => {
|
|
36
|
+
const machine2 = cli("uname -m").trim();
|
|
37
|
+
if (machine2 === "x86_64" || machine2 === "amd64") return "x64";
|
|
38
|
+
if (machine2 === "aarch64" || machine2 === "arm64") return "arm64";
|
|
39
|
+
if (machine2 === "i686" || machine2 === "i386") return "ia32";
|
|
40
|
+
if (machine2.startsWith("arm")) return "arm";
|
|
41
|
+
return machine2;
|
|
42
|
+
};
|
|
43
|
+
const machine = () => cli("uname -m").trim();
|
|
44
|
+
const version = () => cli("uname -v").trim();
|
|
45
|
+
const uptime = () => {
|
|
46
|
+
const _os2 = getOs();
|
|
47
|
+
switch (_os2) {
|
|
48
|
+
case "darwin":
|
|
49
|
+
return darwin.uptime();
|
|
50
|
+
case "linux":
|
|
51
|
+
return linux.uptime();
|
|
52
|
+
default:
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const totalmem = () => {
|
|
57
|
+
const _os2 = getOs();
|
|
58
|
+
switch (_os2) {
|
|
59
|
+
case "darwin":
|
|
60
|
+
return darwin.totalmem();
|
|
61
|
+
case "linux":
|
|
62
|
+
return linux.totalmem();
|
|
63
|
+
default:
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const availableParallelism = () => {
|
|
68
|
+
const c = cpus();
|
|
69
|
+
return c ? c.length : 1;
|
|
70
|
+
};
|
|
71
|
+
const userInfo = () => {
|
|
72
|
+
let uid = 1e3;
|
|
73
|
+
let gid = 100;
|
|
74
|
+
let shell = "";
|
|
75
|
+
try {
|
|
76
|
+
uid = parseInt(cli("id -u"), 10);
|
|
77
|
+
gid = parseInt(cli("id -g"), 10);
|
|
78
|
+
shell = GLib.getenv("SHELL") || "";
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
uid,
|
|
83
|
+
gid,
|
|
84
|
+
username: GLib.get_user_name(),
|
|
85
|
+
homedir: GLib.get_home_dir(),
|
|
86
|
+
shell
|
|
87
|
+
};
|
|
88
|
+
};
|
|
18
89
|
const cpus = () => {
|
|
19
|
-
const
|
|
20
|
-
switch (
|
|
90
|
+
const _os2 = getOs();
|
|
91
|
+
switch (_os2) {
|
|
21
92
|
case "darwin":
|
|
22
93
|
return darwin.cpus();
|
|
23
94
|
case "linux":
|
|
24
95
|
return linux.cpus();
|
|
25
96
|
default:
|
|
26
|
-
console.warn(`${
|
|
97
|
+
console.warn(`${_os2} is not supported!`);
|
|
27
98
|
break;
|
|
28
99
|
}
|
|
29
100
|
};
|
|
30
101
|
const endianness = () => {
|
|
31
|
-
const
|
|
32
|
-
switch (
|
|
102
|
+
const _os2 = getOs();
|
|
103
|
+
switch (_os2) {
|
|
33
104
|
case "darwin":
|
|
34
105
|
return darwin.endianness();
|
|
35
106
|
case "linux":
|
|
36
107
|
return linux.endianness();
|
|
37
108
|
default:
|
|
38
|
-
console.warn(`${
|
|
109
|
+
console.warn(`${_os2} is not supported!`);
|
|
39
110
|
break;
|
|
40
111
|
}
|
|
41
112
|
};
|
|
42
113
|
const freemem = () => {
|
|
43
|
-
const
|
|
44
|
-
switch (
|
|
114
|
+
const _os2 = getOs();
|
|
115
|
+
switch (_os2) {
|
|
45
116
|
case "darwin":
|
|
46
117
|
return darwin.freemem();
|
|
47
118
|
case "linux":
|
|
48
119
|
return linux.freemem();
|
|
49
120
|
default:
|
|
50
|
-
console.warn(`${
|
|
121
|
+
console.warn(`${_os2} is not supported!`);
|
|
51
122
|
break;
|
|
52
123
|
}
|
|
53
124
|
};
|
|
54
125
|
const loadavg = () => {
|
|
55
|
-
const
|
|
56
|
-
switch (
|
|
126
|
+
const _os2 = getOs();
|
|
127
|
+
switch (_os2) {
|
|
57
128
|
case "darwin":
|
|
58
129
|
return darwin.loadavg();
|
|
59
130
|
case "linux":
|
|
60
131
|
return linux.loadavg();
|
|
61
132
|
default:
|
|
62
|
-
console.warn(`${
|
|
133
|
+
console.warn(`${_os2} is not supported!`);
|
|
63
134
|
break;
|
|
64
135
|
}
|
|
65
136
|
};
|
|
66
137
|
const networkInterfaces = () => {
|
|
67
|
-
const
|
|
68
|
-
switch (
|
|
138
|
+
const _os2 = getOs();
|
|
139
|
+
switch (_os2) {
|
|
69
140
|
case "darwin":
|
|
70
141
|
return darwin.networkInterfaces();
|
|
71
142
|
case "linux":
|
|
72
143
|
return linux.networkInterfaces();
|
|
73
144
|
default:
|
|
74
|
-
console.warn(`${
|
|
145
|
+
console.warn(`${_os2} is not supported!`);
|
|
75
146
|
break;
|
|
76
147
|
}
|
|
77
148
|
};
|
|
149
|
+
const getPriority = (pid) => {
|
|
150
|
+
const targetPid = pid === void 0 || pid === 0 ? getPid() : pid;
|
|
151
|
+
try {
|
|
152
|
+
const nice = cli(`ps -o ni= -p ${targetPid}`).trim();
|
|
153
|
+
const val = parseInt(nice, 10);
|
|
154
|
+
if (!isNaN(val)) return val;
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
return 0;
|
|
158
|
+
};
|
|
159
|
+
const setPriority = (pidOrPriority, priority) => {
|
|
160
|
+
let pid;
|
|
161
|
+
let prio;
|
|
162
|
+
if (priority === void 0) {
|
|
163
|
+
prio = pidOrPriority;
|
|
164
|
+
pid = 0;
|
|
165
|
+
} else {
|
|
166
|
+
pid = pidOrPriority;
|
|
167
|
+
prio = priority;
|
|
168
|
+
}
|
|
169
|
+
if (typeof pid !== "number" || !Number.isInteger(pid)) {
|
|
170
|
+
throw new TypeError('The "pid" argument must be an integer');
|
|
171
|
+
}
|
|
172
|
+
if (typeof prio !== "number" || !Number.isInteger(prio) || prio < -20 || prio > 19) {
|
|
173
|
+
throw new RangeError('The "priority" argument must be an integer between -20 and 19');
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const actualPid = pid === 0 ? getPid() : pid;
|
|
177
|
+
cli(`renice -n ${prio} -p ${actualPid}`);
|
|
178
|
+
} catch (err) {
|
|
179
|
+
const error = new Error(`A system error occurred: priority could not be set`);
|
|
180
|
+
error.code = "ERR_SYSTEM_ERROR";
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
var index_default = {
|
|
185
|
+
EOL,
|
|
186
|
+
arch,
|
|
187
|
+
availableParallelism,
|
|
188
|
+
constants,
|
|
189
|
+
cpus,
|
|
190
|
+
devNull,
|
|
191
|
+
endianness,
|
|
192
|
+
freemem,
|
|
193
|
+
getPriority,
|
|
194
|
+
homedir,
|
|
195
|
+
hostname,
|
|
196
|
+
loadavg,
|
|
197
|
+
machine,
|
|
198
|
+
networkInterfaces,
|
|
199
|
+
platform,
|
|
200
|
+
release,
|
|
201
|
+
setPriority,
|
|
202
|
+
tmpdir,
|
|
203
|
+
totalmem,
|
|
204
|
+
type,
|
|
205
|
+
uptime,
|
|
206
|
+
userInfo,
|
|
207
|
+
version
|
|
208
|
+
};
|
|
78
209
|
export {
|
|
79
210
|
EOL,
|
|
211
|
+
arch,
|
|
212
|
+
availableParallelism,
|
|
80
213
|
constants,
|
|
81
214
|
cpus,
|
|
215
|
+
index_default as default,
|
|
216
|
+
devNull,
|
|
82
217
|
endianness,
|
|
83
218
|
freemem,
|
|
219
|
+
getPriority,
|
|
84
220
|
homedir,
|
|
85
221
|
hostname,
|
|
86
222
|
loadavg,
|
|
223
|
+
machine,
|
|
87
224
|
networkInterfaces,
|
|
225
|
+
platform,
|
|
88
226
|
release,
|
|
227
|
+
setPriority,
|
|
89
228
|
tmpdir,
|
|
229
|
+
totalmem,
|
|
90
230
|
type,
|
|
91
|
-
|
|
231
|
+
uptime,
|
|
232
|
+
userInfo,
|
|
233
|
+
version
|
|
92
234
|
};
|
package/lib/esm/linux.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import GLib from "@girs/glib-2.0";
|
|
1
2
|
import { createSubnet } from "./createSubnet.js";
|
|
2
3
|
import { cli } from "@gjsify/utils";
|
|
4
|
+
const byteArray = imports.byteArray;
|
|
3
5
|
const EOL = /\r\n|\n/;
|
|
6
|
+
function readTextFile(path) {
|
|
7
|
+
const [ok, contents] = GLib.file_get_contents(path);
|
|
8
|
+
if (!ok || !contents) return "";
|
|
9
|
+
return byteArray.toString(contents);
|
|
10
|
+
}
|
|
4
11
|
const getIPv4Subnet = createSubnet(32, 8, 10, ".");
|
|
5
12
|
const getIPv6Subnet = createSubnet(128, 16, 16, ":");
|
|
6
13
|
function parseInterfaces(info) {
|
|
7
14
|
info = info.trim();
|
|
8
|
-
if (info.length < 1)
|
|
9
|
-
return;
|
|
15
|
+
if (info.length < 1) return;
|
|
10
16
|
let iface = [], mac;
|
|
11
17
|
for (let line, lines = info.split(EOL), i = 0; i < lines.length; i++) {
|
|
12
18
|
line = lines[i];
|
|
@@ -26,25 +32,22 @@ function parseInterfaces(info) {
|
|
|
26
32
|
break;
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
|
-
if (mac)
|
|
30
|
-
this[info.slice(0, info.indexOf(":"))] = iface;
|
|
35
|
+
if (mac) this[info.slice(0, info.indexOf(":"))] = iface;
|
|
31
36
|
}
|
|
32
37
|
;
|
|
33
38
|
const cpus = () => {
|
|
34
39
|
const PROCESSOR = /^processor\s*:\s*(\d+)/i;
|
|
35
40
|
const NAME = /^model[\s_]+name\s*:([^\r\n]+)/i;
|
|
36
41
|
const FREQ = /^cpu[\s_]+MHz\s*:\s*(\d+)/i;
|
|
37
|
-
const
|
|
42
|
+
const result = [];
|
|
38
43
|
let cpu;
|
|
39
|
-
|
|
44
|
+
readTextFile("/proc/cpuinfo").split(EOL).forEach((line) => {
|
|
40
45
|
switch (true) {
|
|
41
46
|
case PROCESSOR.test(line):
|
|
42
|
-
|
|
47
|
+
result[RegExp.$1.trim()] = cpu = {
|
|
43
48
|
model: "",
|
|
44
49
|
speed: 0,
|
|
45
|
-
|
|
46
|
-
return {};
|
|
47
|
-
}
|
|
50
|
+
times: { user: 0, nice: 0, sys: 0, idle: 0, irq: 0 }
|
|
48
51
|
};
|
|
49
52
|
break;
|
|
50
53
|
case NAME.test(line):
|
|
@@ -55,32 +58,114 @@ const cpus = () => {
|
|
|
55
58
|
break;
|
|
56
59
|
}
|
|
57
60
|
});
|
|
58
|
-
|
|
61
|
+
try {
|
|
62
|
+
const statLines = readTextFile("/proc/stat").split(EOL);
|
|
63
|
+
for (const line of statLines) {
|
|
64
|
+
const m = /^cpu(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\d+\s+(\d+)/.exec(line);
|
|
65
|
+
if (m && result[parseInt(m[1], 10)]) {
|
|
66
|
+
result[parseInt(m[1], 10)].times = {
|
|
67
|
+
user: parseInt(m[2], 10) * 10,
|
|
68
|
+
nice: parseInt(m[3], 10) * 10,
|
|
69
|
+
sys: parseInt(m[4], 10) * 10,
|
|
70
|
+
idle: parseInt(m[5], 10) * 10,
|
|
71
|
+
irq: parseInt(m[6], 10) * 10
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
59
78
|
};
|
|
60
79
|
const endianness = () => "LE";
|
|
61
80
|
const freemem = () => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
81
|
+
const content = readTextFile("/proc/meminfo");
|
|
82
|
+
let memFree = 0;
|
|
83
|
+
for (const line of content.split("\n")) {
|
|
84
|
+
const available = /^MemAvailable:\s+(\d+)\s+kB/.exec(line);
|
|
85
|
+
if (available) return parseInt(available[1], 10) * 1024;
|
|
86
|
+
const free = /^MemFree:\s+(\d+)\s+kB/.exec(line);
|
|
87
|
+
if (free) memFree = parseInt(free[1], 10) * 1024;
|
|
88
|
+
}
|
|
89
|
+
return memFree;
|
|
65
90
|
};
|
|
66
91
|
const loadavg = () => /(\d+(?:\.\d+))\s+(\d+(?:\.\d+))\s+(\d+(?:\.\d+))/.test(
|
|
67
|
-
|
|
92
|
+
readTextFile("/proc/loadavg")
|
|
68
93
|
) && [
|
|
69
94
|
parseFloat(RegExp.$1),
|
|
70
95
|
parseFloat(RegExp.$2),
|
|
71
96
|
parseFloat(RegExp.$3)
|
|
72
97
|
];
|
|
73
98
|
const networkInterfaces = () => {
|
|
99
|
+
try {
|
|
100
|
+
const ifaces = {};
|
|
101
|
+
cli("ip addr").split(/^\d+:\s+/m).forEach(parseInterfaces, ifaces);
|
|
102
|
+
return ifaces;
|
|
103
|
+
} catch {
|
|
104
|
+
return readNetworkInterfacesFromProc();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
function readNetworkInterfacesFromProc() {
|
|
74
108
|
const ifaces = {};
|
|
75
|
-
|
|
109
|
+
const macs = {};
|
|
110
|
+
try {
|
|
111
|
+
const netDev = readTextFile("/proc/net/dev");
|
|
112
|
+
for (const line of netDev.split("\n").slice(2)) {
|
|
113
|
+
const name = line.split(":")[0]?.trim();
|
|
114
|
+
if (!name) continue;
|
|
115
|
+
ifaces[name] = [];
|
|
116
|
+
try {
|
|
117
|
+
macs[name] = readTextFile(`/sys/class/net/${name}/address`).trim();
|
|
118
|
+
} catch {
|
|
119
|
+
macs[name] = "00:00:00:00:00:00";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} catch {
|
|
123
|
+
return ifaces;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const inet6 = readTextFile("/proc/net/if_inet6");
|
|
127
|
+
for (const line of inet6.split("\n")) {
|
|
128
|
+
const parts = line.trim().split(/\s+/);
|
|
129
|
+
if (parts.length < 6) continue;
|
|
130
|
+
const [addrHex, , prefixLen, , , devName] = parts;
|
|
131
|
+
const groups = addrHex.match(/.{4}/g);
|
|
132
|
+
if (!groups || !ifaces[devName]) continue;
|
|
133
|
+
ifaces[devName].push({
|
|
134
|
+
address: groups.join(":"),
|
|
135
|
+
netmask: getIPv6Subnet(prefixLen),
|
|
136
|
+
family: "IPv6",
|
|
137
|
+
mac: macs[devName] || "00:00:00:00:00:00",
|
|
138
|
+
internal: devName === "lo"
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
if (ifaces["lo"]) {
|
|
144
|
+
ifaces["lo"].unshift({
|
|
145
|
+
address: "127.0.0.1",
|
|
146
|
+
netmask: "255.0.0.0",
|
|
147
|
+
family: "IPv4",
|
|
148
|
+
mac: macs["lo"] || "00:00:00:00:00:00",
|
|
149
|
+
internal: true
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
for (const name of Object.keys(ifaces)) {
|
|
153
|
+
if (ifaces[name].length === 0) delete ifaces[name];
|
|
154
|
+
}
|
|
76
155
|
return ifaces;
|
|
77
|
-
}
|
|
156
|
+
}
|
|
78
157
|
const totalmem = () => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
158
|
+
const content = readTextFile("/proc/meminfo");
|
|
159
|
+
for (const line of content.split("\n")) {
|
|
160
|
+
const match = /^MemTotal:\s+(\d+)\s+kB/.exec(line);
|
|
161
|
+
if (match) return parseInt(match[1], 10) * 1024;
|
|
162
|
+
}
|
|
163
|
+
return 0;
|
|
164
|
+
};
|
|
165
|
+
const uptime = () => {
|
|
166
|
+
const content = readTextFile("/proc/uptime").trim();
|
|
167
|
+
return parseFloat(content.split(" ")[0]) || 0;
|
|
82
168
|
};
|
|
83
|
-
const uptime = () => (Date.now() - Date.parse(cli("uptime -s").replace(" ", "T"))) / 1e3;
|
|
84
169
|
export {
|
|
85
170
|
cpus,
|
|
86
171
|
endianness,
|