From e640c6e2457e92e2c10608584a05ca8db0a436b8 Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 30 Oct 2022 09:57:17 +0100 Subject: [PATCH] Kernel, libc, userspace: Add file timestamps (atime,ctime,mtime) --- apps/src/stat.c | 5 +++++ kernel/include/fs/VFS.h | 3 +++ kernel/src/fs/devices/Console.cpp | 3 +++ kernel/src/fs/devices/DeviceFS.cpp | 3 +++ kernel/src/fs/devices/Keyboard.cpp | 3 +++ kernel/src/fs/devices/NullDevice.cpp | 3 +++ kernel/src/fs/devices/Random.cpp | 3 +++ kernel/src/fs/devices/Serial.cpp | 3 +++ kernel/src/fs/devices/Uptime.cpp | 3 +++ kernel/src/fs/devices/Version.cpp | 3 +++ kernel/src/init/InitRD.cpp | 7 +++++++ kernel/src/sys/clock.cpp | 10 ++++++++++ kernel/src/sys/stat.cpp | 9 ++++++--- libs/libc/include/sys/stat.h | 6 +++--- 14 files changed, 58 insertions(+), 6 deletions(-) diff --git a/apps/src/stat.c b/apps/src/stat.c index b78e6eff..7e158bea 100644 --- a/apps/src/stat.c +++ b/apps/src/stat.c @@ -2,6 +2,7 @@ #include #include #include +#include const char* mode_to_string(mode_t mode) { @@ -55,6 +56,10 @@ int main(int argc, char** argv) printf("Owned by: %s\n", own->pw_name); printf("Mode: %s\n", mode_to_string(st.st_mode)); + printf("Accessed on: %s", ctime(&st.st_atime)); + printf("Modified on: %s", ctime(&st.st_mtime)); + printf("Changed on: %s", ctime(&st.st_ctime)); + endpwent(); return EXIT_SUCCESS; diff --git a/kernel/include/fs/VFS.h b/kernel/include/fs/VFS.h index 924b05ec..a8111177 100644 --- a/kernel/include/fs/VFS.h +++ b/kernel/include/fs/VFS.h @@ -41,6 +41,9 @@ namespace VFS Node* link; int uid; int gid; + uint64_t atime; + uint64_t ctime; + uint64_t mtime; mode_t mode; }; diff --git a/kernel/src/fs/devices/Console.cpp b/kernel/src/fs/devices/Console.cpp index ad0d05c7..8ba7f978 100644 --- a/kernel/src/fs/devices/Console.cpp +++ b/kernel/src/fs/devices/Console.cpp @@ -5,6 +5,8 @@ #include "std/stdlib.h" #include "std/string.h" +extern uint64_t clock_boot(); + VFS::Node* ConsoleDevice::create_new(const char* devname) { VFS::Node* dev = new VFS::Node; @@ -16,6 +18,7 @@ VFS::Node* ConsoleDevice::create_new(const char* devname) dev->tty = 1; dev->uid = dev->gid = 0; dev->mode = 0222; + dev->atime = dev->ctime = dev->mtime = clock_boot(); strncpy(dev->name, devname, sizeof(dev->name)); return dev; } diff --git a/kernel/src/fs/devices/DeviceFS.cpp b/kernel/src/fs/devices/DeviceFS.cpp index ffe91078..e415ca05 100644 --- a/kernel/src/fs/devices/DeviceFS.cpp +++ b/kernel/src/fs/devices/DeviceFS.cpp @@ -16,6 +16,8 @@ VFS::Node* devfs_root = nullptr; VFS::Node* devfs_files[DEVFS_MAX_FILES]; int devfs_file_count = 0; +extern uint64_t clock_boot(); + VFS::Node* DeviceFS::get() { if (devfs_root) return devfs_root; @@ -27,6 +29,7 @@ VFS::Node* DeviceFS::get() devfs_root->readdir_func = DeviceFS::readdir; devfs_root->mode = 0755; devfs_root->uid = devfs_root->gid = 0; + devfs_root->atime = devfs_root->ctime = devfs_root->mtime = clock_boot(); strncpy(devfs_root->name, "dev", sizeof(devfs_root->name)); devfs_files[devfs_file_count++] = VersionDevice::create_new("version"); diff --git a/kernel/src/fs/devices/Keyboard.cpp b/kernel/src/fs/devices/Keyboard.cpp index e3d0ed4f..8a1813d4 100644 --- a/kernel/src/fs/devices/Keyboard.cpp +++ b/kernel/src/fs/devices/Keyboard.cpp @@ -16,6 +16,8 @@ int KeyboardDevice::would_block(VFS::Node*) return kbd_bufsize == 0; } +extern uint64_t clock_boot(); + VFS::Node* KeyboardDevice::create_new(const char* devname) { VFS::Node* dev = new VFS::Node; @@ -28,6 +30,7 @@ VFS::Node* KeyboardDevice::create_new(const char* devname) dev->tty = 1; dev->uid = dev->gid = 0; dev->mode = 0444; + dev->atime = dev->ctime = dev->mtime = clock_boot(); strncpy(dev->name, devname, sizeof(dev->name)); return dev; } diff --git a/kernel/src/fs/devices/NullDevice.cpp b/kernel/src/fs/devices/NullDevice.cpp index 7fcecc8f..b49b578c 100644 --- a/kernel/src/fs/devices/NullDevice.cpp +++ b/kernel/src/fs/devices/NullDevice.cpp @@ -3,6 +3,8 @@ #include "std/stdlib.h" #include "std/string.h" +extern uint64_t clock_boot(); + VFS::Node* NullDevice::create_new(const char* devname) { VFS::Node* dev = new VFS::Node; @@ -14,6 +16,7 @@ VFS::Node* NullDevice::create_new(const char* devname) dev->flags = 0; dev->uid = dev->gid = 0; dev->mode = 0666; + dev->atime = dev->ctime = dev->mtime = clock_boot(); strncpy(dev->name, devname, sizeof(dev->name)); return dev; } diff --git a/kernel/src/fs/devices/Random.cpp b/kernel/src/fs/devices/Random.cpp index d7eeb6a4..0cc8c27b 100644 --- a/kernel/src/fs/devices/Random.cpp +++ b/kernel/src/fs/devices/Random.cpp @@ -6,6 +6,8 @@ #include "std/stdlib.h" #include "std/string.h" +extern uint64_t clock_boot(); + VFS::Node* RandomDevice::create_new(const char* devname) { VFS::Node* dev = new VFS::Node; @@ -16,6 +18,7 @@ VFS::Node* RandomDevice::create_new(const char* devname) dev->flags = 0; dev->uid = dev->gid = 0; dev->mode = 0444; + dev->atime = dev->ctime = dev->mtime = clock_boot(); strncpy(dev->name, devname, sizeof(dev->name)); return dev; } diff --git a/kernel/src/fs/devices/Serial.cpp b/kernel/src/fs/devices/Serial.cpp index 1fe92824..d1e2785a 100644 --- a/kernel/src/fs/devices/Serial.cpp +++ b/kernel/src/fs/devices/Serial.cpp @@ -5,6 +5,8 @@ #include "std/stdlib.h" #include "std/string.h" +extern uint64_t clock_boot(); + VFS::Node* SerialDevice::create_new(const char* devname) { VFS::Node* dev = new VFS::Node; @@ -15,6 +17,7 @@ VFS::Node* SerialDevice::create_new(const char* devname) dev->flags = 0; dev->uid = dev->gid = 0; dev->mode = 0200; + dev->atime = dev->ctime = dev->mtime = clock_boot(); strncpy(dev->name, devname, sizeof(dev->name)); return dev; } diff --git a/kernel/src/fs/devices/Uptime.cpp b/kernel/src/fs/devices/Uptime.cpp index ab45cb42..a518ce37 100644 --- a/kernel/src/fs/devices/Uptime.cpp +++ b/kernel/src/fs/devices/Uptime.cpp @@ -4,6 +4,8 @@ #include "std/string.h" #include "thread/PIT.h" +extern uint64_t clock_boot(); + VFS::Node* UptimeDevice::create_new(const char* devname) { VFS::Node* dev = new VFS::Node; @@ -14,6 +16,7 @@ VFS::Node* UptimeDevice::create_new(const char* devname) dev->flags = 0; dev->uid = dev->gid = 0; dev->mode = 0444; + dev->atime = dev->ctime = dev->mtime = clock_boot(); strncpy(dev->name, devname, sizeof(dev->name)); return dev; } diff --git a/kernel/src/fs/devices/Version.cpp b/kernel/src/fs/devices/Version.cpp index c01c4aae..0a1ac394 100644 --- a/kernel/src/fs/devices/Version.cpp +++ b/kernel/src/fs/devices/Version.cpp @@ -4,6 +4,8 @@ #include "std/stdlib.h" #include "std/string.h" +extern uint64_t clock_boot(); + VFS::Node* VersionDevice::create_new(const char* devname) { VFS::Node* dev = new VFS::Node; @@ -14,6 +16,7 @@ VFS::Node* VersionDevice::create_new(const char* devname) dev->flags = 0; dev->uid = dev->gid = 0; dev->mode = 0444; + dev->atime = dev->ctime = dev->mtime = clock_boot(); strncpy(dev->name, devname, sizeof(dev->name)); return dev; } diff --git a/kernel/src/init/InitRD.cpp b/kernel/src/init/InitRD.cpp index 82382ded..d7c7aae8 100644 --- a/kernel/src/init/InitRD.cpp +++ b/kernel/src/init/InitRD.cpp @@ -18,6 +18,9 @@ static bool initrd_initialized = false; static VFS::Node initrd_root; +extern uint64_t clock_boot(); // defined in sys/clock.cpp +extern uint64_t clock_now(); + bool InitRD::is_initialized() { return initrd_initialized; @@ -234,6 +237,7 @@ int initrd_mkdir(VFS::Node* node, const char* name, mode_t mode) // FIXME: Retur new_node.type = VFS_DIRECTORY; new_node.mode = mode; new_node.uid = new_node.gid = 0; + new_node.atime = new_node.ctime = new_node.mtime = clock_now(); strncpy(new_node.name, name, sizeof(new_node.name)); InitRD::Directory dir; strncpy(dir.name, name, sizeof(dir.name)); @@ -293,6 +297,7 @@ static bool initrd_register_dir(InitRD::Directory& dir, uint64_t inode) node.length = 0; node.mode = 0755; node.uid = node.gid = 0; + node.atime = node.ctime = node.mtime = clock_boot(); strncpy(node.name, buffer, sizeof(node.name)); strncpy(dir.name, buffer, sizeof(dir.name)); @@ -354,6 +359,7 @@ static bool initrd_register_file(InitRD::File& f, uint64_t inode) node.type = VFS_FILE; node.mode = f.mode & 07555; // don't allow writing node.uid = node.gid = 0; + node.atime = node.ctime = node.mtime = clock_boot(); strncpy(node.name, buffer, sizeof(node.name)); strncpy(f.name, buffer, sizeof(f.name)); @@ -398,6 +404,7 @@ static void initrd_initialize_root() initrd_root.type |= VFS_DIRECTORY; initrd_root.mode = 0755; initrd_root.uid = initrd_root.gid = 0; + initrd_root.atime = initrd_root.ctime = initrd_root.mtime = clock_boot(); InitRD::Directory& root = dirs[0]; total_dirs++; strncpy(initrd_root.name, "initrd", sizeof(initrd_root.name)); diff --git a/kernel/src/sys/clock.cpp b/kernel/src/sys/clock.cpp index 99374f32..1d13b879 100644 --- a/kernel/src/sys/clock.cpp +++ b/kernel/src/sys/clock.cpp @@ -70,4 +70,14 @@ extern BOOTBOOT bootboot; void clock_init() { unix_boot_time = unix_boottime(bootboot.datetime); +} + +uint64_t clock_now() +{ + return unix_boot_time + (PIT::ms_since_boot / 1000); +} + +uint64_t clock_boot() +{ + return unix_boot_time; } \ No newline at end of file diff --git a/kernel/src/sys/stat.cpp b/kernel/src/sys/stat.cpp index 8233e715..d9eaa750 100644 --- a/kernel/src/sys/stat.cpp +++ b/kernel/src/sys/stat.cpp @@ -16,9 +16,9 @@ struct stat // FIXME: This struct is quite stubbed out. int st_dev; // FIXME: Implement this. uid_t st_uid; gid_t st_gid; - time_t st_atime; // Not implemented. - time_t st_mtime; // Not implemented. - time_t st_ctime; // Not implemented. + time_t st_atime; + time_t st_mtime; + time_t st_ctime; }; void do_stat(Context* context, VFS::Node* node, struct stat* buf) @@ -34,6 +34,9 @@ void do_stat(Context* context, VFS::Node* node, struct stat* buf) kstat->st_size = node->length; kstat->st_uid = node->uid; kstat->st_gid = node->gid; + kstat->st_atime = node->atime; + kstat->st_ctime = node->ctime; + kstat->st_mtime = node->mtime; release_user_ref(kstat); context->rax = 0; } diff --git a/libs/libc/include/sys/stat.h b/libs/libc/include/sys/stat.h index f45710d1..6602677d 100644 --- a/libs/libc/include/sys/stat.h +++ b/libs/libc/include/sys/stat.h @@ -12,9 +12,9 @@ struct stat // FIXME: This struct is quite stubbed out. int st_dev; // Not implemented. uid_t st_uid; gid_t st_gid; - time_t st_atime; // Not implemented. - time_t st_mtime; // Not implemented. - time_t st_ctime; // Not implemented. + time_t st_atime; + time_t st_mtime; + time_t st_ctime; }; /* Type of file. */