From b3c2b90ef4adab7c0710f161949d8cf27e254a77 Mon Sep 17 00:00:00 2001
From: sakura <1927346336@qq.com>
Date: Fri, 1 Nov 2024 06:24:03 +0000
Subject: [PATCH] getdents

---
 kernel/syscall.c |  6 +++---
 kernel/sysfile.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/kernel/syscall.c b/kernel/syscall.c
index 4627dc0..7556d1f 100644
--- a/kernel/syscall.c
+++ b/kernel/syscall.c
@@ -130,7 +130,7 @@ extern uint64 sys_openat(void);
 extern uint64 sys_dup3(void);
 extern uint64 sys_mount(void);
 extern uint64 sys_umount2(void);
-// extern uint64 sys_getdents64(void);
+extern uint64 sys_getdents64(void);
 
 static uint64 (*syscalls[])(void) = {
   [SYS_fork]        sys_fork,
@@ -175,7 +175,7 @@ static uint64 (*syscalls[])(void) = {
   [SYS_pipe2]         sys_pipe,
   [SYS_mount]         sys_mount,
   [SYS_umount2]       sys_umount2,
-  // [SYS_getdents64]    sys_getdents64,
+  [SYS_getdents64]    sys_getdents64,
 };
 
 static char *sysnames[] = {
@@ -220,7 +220,7 @@ static char *sysnames[] = {
     [SYS_pipe2] "pipe2",
     [SYS_mount] "sys_mount",
     [SYS_umount2] "sys_umount2",
-    // [SYS_getdents64]  "getdents64",
+    [SYS_getdents64]  "getdents64",
 };
 
 void
diff --git a/kernel/sysfile.c b/kernel/sysfile.c
index b52c9de..911a364 100644
--- a/kernel/sysfile.c
+++ b/kernel/sysfile.c
@@ -620,3 +620,56 @@ fail:
     eput(src);
   return -1;
 }
+
+struct linux_dirent64
+{
+  uint64 d_ino;
+  uint32 d_off;
+  unsigned short d_reclen;
+  unsigned char d_type;
+  char d_name[];
+};
+
+uint64
+sys_getdents64(void)
+{
+  int fd, len;
+  uint64 addr;
+  struct file *f;
+  int nread = 0;
+  struct dirent de;
+  int count = 0;
+  int ret;
+  struct linux_dirent64 tmp;
+
+  if (argint(0, &fd) < 0 || argint(2, &len) < 0 || argaddr(1, &addr) < 0)
+  {
+    return -1;
+  }
+  if (fd < 0 || fd >= NOFILE || (f = myproc()->ofile[fd]) == NULL)
+    return -1;
+
+  while (nread + (int)(sizeof(tmp)) <= len)
+  {
+    elock(f->ep);
+    // 跳过empty slots
+    while ((ret = enext(f->ep, &de, f->off, &count)) == 0)
+    { 
+      f->off += count * 32;
+    }
+    eunlock(f->ep);
+    // 目录结尾
+    if (ret == -1) 
+      return nread;
+
+    f->off += count * 32;
+    safestrcpy(tmp.d_name, de.filename, strlen(de.filename) + 1);
+
+    if (copyout2(addr, (char *)&tmp, sizeof(tmp)) < 0)
+      return -1;
+
+    addr += sizeof(tmp);
+    nread += (int)(sizeof(tmp));
+  }
+  return nread;
+}
-- 
GitLab