From 5674011460c570ae9f1e02d47d1b9430403b81b4 Mon Sep 17 00:00:00 2001 From: Ronald1985 Date: Tue, 7 Nov 2023 22:16:58 +0000 Subject: [PATCH] Started to work on process functions. These aren't complete, but adding them now so they can be used. As currently only thing to do is ensure we get CPU and memory usage for a process. --- sysinfo.odin | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/sysinfo.odin b/sysinfo.odin index e52f858..65dab8b 100644 --- a/sysinfo.odin +++ b/sysinfo.odin @@ -376,3 +376,122 @@ get_system_uptime_in_seconds :: proc() -> (int, bool) { return uptime_seconds, true } + +get_total_number_of_processes :: proc () -> (int) { + fd, open_err := os.open("/proc") + if open_err != 0 { + return 0 + } + defer os.close(fd) + + files, err := os.read_dir(fd, -1) + if err != 0 { + return 0 + } + defer os.file_info_slice_delete(files) + + number_of_processes := 0 + for file in files { + if file.is_dir && strconv.atoi(file.name) != 0 { + number_of_processes += 1 + } + } + + return number_of_processes +} + +// https://www.baeldung.com/linux/total-process-cpu-usage +get_process_details :: proc(pid: int) -> (Process, bool) { + process: Process + + process.pid = pid + + buf: [256]u8 + filename := fmt.tprintf("/proc/%d/comm", pid) + fd, err := os.open(filename) + if err != os.ERROR_NONE { + return {}, false + } + _, err = os.read_full(fd, buf[0:]) + if err != os.ERROR_NONE { + return {}, false + } + temp := string(buf[:])[:strings.index(string(buf[:]), "\n")] + process.name = strings.clone(temp) + + filename = fmt.tprintf("/proc/%d/cmdline", pid) + fd, err = os.open(filename) + if err != os.ERROR_NONE { + return {}, false + } + _, err = os.read_full(fd, buf[0:]) + if err != os.ERROR_NONE { + return {}, false + } + process.command = strings.clone(string(buf[:])) + + // filename = fmt.tprintf("/proc/%d/stat", pid) + // fd, err = os.open(filename) + // if err != os.ERROR_NONE { + // return {}, false + // } + // _, err = os.read_full(fd, buf[0:]) + // if err != os.ERROR_NONE { + // return {}, false + // } + + // fields := strings.fields(string(buf)) + + // utime := strconv.atoi(fields[13]) + // stime := strconv.atoi(fields[14]) + // process_start_time := strconv.atoi(fields[21]) + + return process, true +} + +get_processes :: proc() -> ([]Process, bool) { + fd, open_err := os.open("/proc") + if open_err != 0 { + return nil, false + } + defer os.close(fd) + + files, err := os.read_dir(fd, -1) + if err != 0 { + return nil, false + } + defer os.file_info_slice_delete(files) + + processes: [dynamic]Process + process: Process + ok: bool + current_process := 0 + for file in files { + if file.is_dir && strconv.atoi(file.name) != 0 { + process, ok = get_process_details(strconv.atoi(file.name)) + if !ok { + delete(processes) + return nil, false + } + + append(&processes, process) + + current_process += 1 + } + } + + return processes[:], true +} + +process_delete :: proc(process: Process, allocator := context.allocator) { + delete(process.name) + delete(process.command) +} + +process_slice_delete :: proc(processes: []Process, allocator := context.allocator) { + for process in processes { + process_delete(process, allocator) + } + + delete(processes, allocator) +}