diff --git a/userspace/CMakeLists.txt b/userspace/CMakeLists.txt index aaedf8a384..276d01966f 100644 --- a/userspace/CMakeLists.txt +++ b/userspace/CMakeLists.txt @@ -10,6 +10,7 @@ set(USERSPACE_PROJECTS id init ls + meminfo mmap-shared-test poweroff Shell diff --git a/userspace/meminfo/CMakeLists.txt b/userspace/meminfo/CMakeLists.txt new file mode 100644 index 0000000000..0094e79704 --- /dev/null +++ b/userspace/meminfo/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.26) + +project(meminfo CXX) + +set(SOURCES + main.cpp +) + +add_executable(meminfo ${SOURCES}) +target_compile_options(meminfo PUBLIC -O2 -g) +target_link_libraries(meminfo PUBLIC libc) + +add_custom_target(meminfo-install + COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/meminfo ${BANAN_BIN}/ + DEPENDS meminfo + USES_TERMINAL +) diff --git a/userspace/meminfo/main.cpp b/userspace/meminfo/main.cpp new file mode 100644 index 0000000000..b9fbbefe5d --- /dev/null +++ b/userspace/meminfo/main.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include + +bool is_only_digits(const char* str) +{ + while (*str) + if (!isdigit(*str++)) + return false; + return true; +} + +int main() +{ + DIR* proc = opendir("/proc"); + if (proc == nullptr) + { + perror("opendir"); + return 1; + } + + char path_buffer[128] {}; + while (dirent* proc_ent = readdir(proc)) + { + if (proc_ent->d_type != DT_DIR) + continue; + if (!is_only_digits(proc_ent->d_name)) + continue; + + strcpy(path_buffer, proc_ent->d_name); + strcat(path_buffer, "/meminfo"); + + int fd = openat(dirfd(proc), path_buffer, O_RDONLY); + if (fd == -1) + { + perror("openat"); + continue; + } + + proc_meminfo_t meminfo; + if (read(fd, &meminfo, sizeof(meminfo)) == -1) + perror("read"); + else + { + printf("process:\n"); + printf(" pid: %s\n", proc_ent->d_name); + printf(" vmem: %zu pages (%zu bytes)\n", meminfo.virt_pages, meminfo.page_size * meminfo.virt_pages); + } + + close(fd); + } + + closedir(proc); +}