/** * OS Module * Features: * - Provides system information (uptime, memory, disk, CPU ID). * - Executes shell commands. * - Manages device modes and rebooting. * * Usage: * - Accessing OS-level and hardware-specific information and controls. * * Doc/Demo : https://github.com/DejaOS/DejaOS */ import { osClass } from './libvbar-m-dxos.so' import dxMap from './dxMap.js' import * as std from 'std'; const dxOs = {}; // Create a singleton instance of the native osClass. // This is executed only once when the module is first imported due to the nature of ES modules. const osObj = new osClass(); /** * Get the running time of system startup (in seconds). * @returns {number} Running time. */ dxOs.getUptime = function () { return osObj.getUptime(); } /** * Get the total memory of the system (in bytes). * @returns {number} Total memory. */ dxOs.getTotalmem = function () { return osObj.getTotalmem(); } /** * Retrieve the remaining memory of the system (in bytes). * @returns {number} Remaining memory. */ dxOs.getFreemem = function () { return osObj.getFreemem(); } /** * Get the total number of available disks in the system (in bytes). * @param {string} [path="/"] - The disk partition name (e.g., "/"). * @returns {number} Total disk space. */ dxOs.getTotaldisk = function (path) { return osObj.getTotaldisk(path || "/"); } /** * Retrieve the remaining available amount of system disk (in bytes). * @param {string} [path="/"] - The disk partition name (e.g., "/"). * @returns {number} Free disk space. */ dxOs.getFreedisk = function (path) { return osObj.getFreedisk(path || "/"); } /** * Get CPU ID. * @returns {string} CPU ID. */ dxOs.getCpuid = function () { // The C function expects a buffer size. 33 is a safe length for the CPU ID. return osObj.getCpuid(33); } /** * Get device UUID. * @returns {string} Device UUID. */ dxOs.getUuid = function () { // The C function expects a buffer size. 19 is a safe length for the UUID. return osObj.getUuid(19); } /** * Get the device's serial number (SN). * It first tries to read from '/etc/.sn'. If that fails, it falls back to the device UUID. * This operation is now handled in C layer to hide file paths. * @returns {string} The device's serial number. */ dxOs.getSn = function () { return osObj.getSn(); } /** * Obtain the MAC address calculated through UUID, which can be used to initialize the network card. * @returns {string} MAC address in the format 'b2:a1:63:3f:99:b6'. */ dxOs.getUuid2mac = function () { // The C function expects a buffer size. 19 is a safe length. return osObj.getUuid2mac(19); } /** * Get CPU usage rate. * @returns {number} A number not greater than 100. */ dxOs.getFreecpu = function () { return osObj.getFreecpu(); } /** * Execute a shell command without printing the result to the terminal. * @param {string} cmd - The command to execute. * @returns {number} The exit code of the command. */ dxOs.system = function (cmd) { return osObj.system(cmd); } /** * Execute a shell command and print the result to the terminal. * @param {string} cmd - The command to execute. * @returns {number} The exit code of the command. */ dxOs.systemBrief = function (cmd) { return osObj.systemBrief(cmd); } /** * Execute a shell command and return the result as a string. * @param {string} cmd - The command to execute. * @param {number} resLen - The maximum length of the result to receive. * @returns {string} The command's stdout result. */ dxOs.systemWithRes = function (cmd, resLen) { return osObj.systemWithRes(cmd, resLen); } /** * Execute a shell command and wait for it to complete. * @param {string} cmd - The command to execute. * @returns {number} The exit code of the command. */ dxOs.systemBlocked = function (cmd) { return osObj.systemBlocked(cmd); } /** * Asynchronously restart the device after a delay. * @param {number} delay_s - The delay in seconds before restarting. * @returns {number} Result of the operation. */ dxOs.asyncReboot = function (delay_s) { return osObj.asyncReboot(delay_s); } /** * Switch device mode. The device will restart after switching. * @param {string} mode - The target mode. Must be one of `"dev"`, `"test"`, `"prod"`, `"safe"`. * @returns {boolean} `true` if the mode switch was initiated, `false` otherwise. */ dxOs.setMode = function (mode) { return osObj.setMode(mode); } /** * Query current device mode. * @returns {string|null} * - `string`: The current mode name (Must be one of `"dev"`, `"test"`, `"prod"`, `"safe"`). * - `null`: If the mode file is not found or is empty. */ dxOs.getMode = function () { return osObj.getMode(); } /** * @namespace dxOs.sync * @description Provides a simple mechanism for synchronous-like communication between asynchronous parts of an application. * Note: This is a simplified implementation and may not be suitable for complex scenarios. */ dxOs.sync = { /** * Waits for a response on a specific topic. * @param {string} topic - The topic to wait for. * @param {number} timeout - Timeout in milliseconds. * @returns {*} The data received on the topic, or undefined if it times out. */ request: function (topic, timeout) { let map = dxMap.get("SYNC"); map.put(topic + "__request__", topic); let count = 0; let data; while (count * 10 < timeout) { data = map.get(topic); if (data !== undefined && data !== null) { break; } std.sleep(10); count += 1; } let res = map.get(topic); map.del(topic); map.del(topic + "__request__"); return res; }, /** * Sends a response to a specific topic. * @param {string} topic - The topic to respond to. * @param {*} data - The data to send. */ response: function (topic, data) { let map = dxMap.get("SYNC"); if (map.get(topic + "__request__") == topic) { map.put(topic, data); } }, }; /** * @private * @description A generic handler for managing component instance pointers by ID. * This is used internally by other DejaOS modules. */ dxOs.handleId = function (name, id, pointer) { // Component name cannot be empty if (name === undefined || name === null || name === "" || typeof name !== 'string') { return } let map = dxMap.get('handleIds') // Handle ID if (id === undefined || id === null || id === "" || typeof id !== 'string') { id = "__" + name + "_default" } if (pointer === undefined || pointer === null || typeof pointer !== 'number') { // If the pointer is empty, it is obtained return map.get(id) } else { // If the pointer is not empty, it is set let isExist = map.get(id) if (isExist) { // Handle already exists return } map.put(id, pointer) } } export default dxOs;