From 69e23a9ca334b4d2cb483cf09812b60744761bf2 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Sun, 14 Sep 2025 19:30:20 +0200 Subject: [PATCH] ioctl() IOCTL_STAT command --- kernel/syscall/ioctl.c | 29 +++++++++++++++++++++++++++++ kernel/vfs/vfs.h | 4 ++-- share/sysdefs/ioctl.h | 10 ++++++++++ ulib/util/util.h | 8 ++++++++ user/tb/main.c | 22 ++++++++++++++++++++++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/kernel/syscall/ioctl.c b/kernel/syscall/ioctl.c index 0c5fd99..811d159 100644 --- a/kernel/syscall/ioctl.c +++ b/kernel/syscall/ioctl.c @@ -133,6 +133,35 @@ int32_t SYSCALL5(sys_ioctl, ioh1, cmd1, arg1, arg2, arg3) { ret = vobj->read(vobj, buffer, len, off); } break; + case IOCTL_STAT: { + if (ioh >= PROC_VFSHANDLES_MAX) { + ret = E_INVALIDARGUMENT; + goto done; + } + + spinlock_acquire(&PROCS.spinlock); + Proc *proc = PROCS.current; + spinlock_release(&PROCS.spinlock); + + VfsObj *vobj = proc->vobjs[ioh]; + + if (vobj == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + VfsStat stat1; + ret = vobj->stat(vobj, &stat1); + + IoctlStat *iostat = (IoctlStat *)arg1; + if (iostat == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + iostat->size = stat1.size; + iostat->type = stat1.type; + } break; default: { ret = E_INVALIDARGUMENT; goto done; diff --git a/kernel/vfs/vfs.h b/kernel/vfs/vfs.h index d79a117..e43d1e4 100644 --- a/kernel/vfs/vfs.h +++ b/kernel/vfs/vfs.h @@ -20,8 +20,8 @@ static const char *vfs_strings[] = { }; enum { - VFS_TYPE_DIR, - VFS_TYPE_FILE, + VFS_TYPE_DIR = 0, + VFS_TYPE_FILE = 1, }; enum { diff --git a/share/sysdefs/ioctl.h b/share/sysdefs/ioctl.h index 07624c3..3e65e4a 100644 --- a/share/sysdefs/ioctl.h +++ b/share/sysdefs/ioctl.h @@ -20,4 +20,14 @@ enum { IOCTL_F_MAKE = 1<<2, }; +enum { + IOCTLSTAT_DIR = 0, + IOCTLSTAT_FILE = 1, +}; + +typedef struct IoctlStat { + size_t size; + int32_t type; +} IoctlStat; + #endif // SHARE_SYSDEFS_IOCTL_H_ diff --git a/ulib/util/util.h b/ulib/util/util.h index 60ff221..bb6eb6a 100644 --- a/ulib/util/util.h +++ b/ulib/util/util.h @@ -1,6 +1,14 @@ #ifndef ULIB_UTIL_UTIL_H_ #define ULIB_UTIL_UTIL_H_ +#include + #define ARRLEN(X) (sizeof((X))/sizeof((X)[0])) +#define ZERO(X) \ +({ \ + string_memset((X), 0, sizeof(*(X))); \ + *(X); \ +}) \ + #endif // ULIB_UTIL_UTIL_H_ diff --git a/user/tb/main.c b/user/tb/main.c index 88ce6bf..b23bf01 100644 --- a/user/tb/main.c +++ b/user/tb/main.c @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include struct { char *modestr; @@ -50,11 +52,31 @@ void process_cmd(char *cmdtext) { } void do_file(char *filepath) { + int32_t ret; + int32_t ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)filepath, IOCTL_F_READ, 0); if (ioh < 0) { LOG(LOG_ERR, "Could not open %s: %s\n", filepath, ERRSTRING(ioh)); return; } + + IoctlStat statbuf = ZERO(&statbuf); + + ioctl(ioh, IOCTL_STAT, (uint64_t)&statbuf, 0, 0); + if (statbuf.type != IOCTLSTAT_FILE) { + LOG(LOG_ERR, "%s is not a file (%d)\n", filepath, statbuf.type); + return; + } + uint8_t *buf = dlmalloc(statbuf.size); + + if ((ret = ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0)) < 0) { + LOG(LOG_ERR, "Could not read %s (%d): %s\n", filepath, ioh, ERRSTRING(ioh)); + goto done; + } + +done: + dlfree(buf); + ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0); } void do_mode_interactive(void) {