syscalls: getdents syscall

This commit is contained in:
Matheus
2023-06-26 21:32:39 -03:00
parent 3b2b8201f6
commit 9bdbdb9378
6 changed files with 170 additions and 9 deletions
+3 -1
View File
@@ -15,6 +15,7 @@ extern syscall_execve
extern syscall_exit
extern syscall_waitpid
extern syscall_munmap
extern syscall_getdents
syscalltab:
dq syscall_print
dq syscall_mmap
@@ -32,7 +33,8 @@ dq syscall_execve
dq syscall_exit
dq syscall_waitpid
dq syscall_munmap
syscallcount equ 16
dq syscall_getdents
syscallcount equ 17
section .text
global arch_syscall_entry
; on entry:
+38 -1
View File
@@ -439,6 +439,42 @@ static int tmpfs_munmap(vnode_t *node, void *addr, uintmax_t offset, int flags,
return 0;
}
static int tmpfs_getdents(vnode_t *node, dent_t *buffer, size_t count, uintmax_t offset, size_t *readcount) {
if (node->type != V_TYPE_DIR)
return ENOTDIR;
VOP_LOCK(node);
tmpfsnode_t *tmpnode = (tmpfsnode_t *)node;
*readcount = 0;
size_t current = 0;
HASHTABLE_FOREACH(&tmpnode->children) {
if (current < offset) {
++current;
continue;
}
if (*readcount == count)
break;
dent_t *ent = &buffer[*readcount];
ent->d_ino = tmpnode->attr.inode;
ent->d_off = offset;
ent->d_reclen = sizeof(dent_t);
ent->d_type = vfs_getposixtype(node->type);
strcpy(ent->d_name, entry->key);
*readcount += 1;
}
VOP_UNLOCK(node);
return 0;
}
static int tmpfs_inactive(vnode_t *node) {
freenode((tmpfsnode_t *)node);
return 0;
@@ -466,7 +502,8 @@ static vops_t vnops = {
.readlink = tmpfs_readlink,
.inactive = tmpfs_inactive,
.mmap = tmpfs_mmap,
.munmap = tmpfs_munmap
.munmap = tmpfs_munmap,
.getdents = tmpfs_getdents
};
static tmpfsnode_t *newnode(vfs_t *vfs, int type) {
+30
View File
@@ -44,4 +44,34 @@ typedef struct {
long __unused[3];
} stat_t;
#define DT_UNKNOWN 0
#define DT_FIFO 1
#define DT_CHR 2
#define DT_DIR 4
#define DT_BLK 6
#define DT_REG 8
#define DT_LNK 10
#define DT_SOCK 12
#define DT_WHT 14
typedef struct {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[1024];
} dent_t;
#define TYPE_FIFO 1
#define TYPE_CHARDEV 2
#define TYPE_DIR 4
#define TYPE_BLOCKDEV 6
#define TYPE_REGULAR 8
#define TYPE_LINK 10
#define TYPE_SOCKET 12
#define GETMODE(m) (0xFFF & (m))
#define GETTYPE(m) (((m) >> 12) & 0xF)
#define MAKETYPE(m) (((m) & 0xF) << 12)
#endif
+23 -3
View File
@@ -89,6 +89,7 @@ typedef struct vops_t {
int (*inactive)(vnode_t *node);
int (*mmap)(vnode_t *node, void *addr, uintmax_t offset, int flags, cred_t *cred);
int (*munmap)(vnode_t *node, void *addr, uintmax_t offset, int flags, cred_t *cred);
int (*getdents)(vnode_t *node, dent_t *buffer, size_t count, uintmax_t offset, size_t *readcount);
} vops_t;
#define VFS_MOUNT(vfs, mp, b, d) (vfs)->ops->mount(vfs, mp, b, d)
@@ -99,7 +100,6 @@ typedef struct vops_t {
#define VOP_LOCK(v) spinlock_acquire(&(v)->lock)
#define VOP_UNLOCK(v) spinlock_release(&(v)->lock)
// these are expected to be called with the vnode(s) locked
#define VOP_OPEN(v, f, c) (*v)->ops->open(v, f, c)
#define VOP_CLOSE(v, f, c) (v)->ops->close(v, f, c)
#define VOP_READ(v, b, s, o, f, r, c) (v)->ops->read(v, b, s, o, f, r, c)
@@ -115,8 +115,7 @@ typedef struct vops_t {
#define VOP_READLINK(v, l, c) (v)->ops->readlink(v, l, c)
#define VOP_MMAP(v, a, o, f, c) (v)->ops->mmap(v, a, o, f, c)
#define VOP_MUNMAP(v, a, o, f, c) (v)->ops->munmap(v, a, o, f, c)
// lock not needed unless atomicity is desired
#define VOP_GETDENTS(v, b, c, o, rc) (v)->ops->getdents(v, b, c, o, rc)
#define VOP_POLL(v, p) (v)->ops->poll(v, p);
#define VOP_HOLD(v) __atomic_add_fetch(&(v)->refcount, 1, __ATOMIC_SEQ_CST)
#define VOP_RELEASE(v) {\
@@ -145,4 +144,25 @@ int vfs_unlink(vnode_t *ref, char *path);
#define VFS_LOOKUP_INTERNAL 0x80000000
int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int flags);
static inline mode_t vfs_getposixtype(int type) {
switch (type) {
case V_TYPE_REGULAR:
return TYPE_REGULAR;
case V_TYPE_DIR:
return TYPE_DIR;
case V_TYPE_CHDEV:
return TYPE_CHARDEV;
case V_TYPE_BLKDEV:
return TYPE_BLOCKDEV;
case V_TYPE_FIFO:
return TYPE_FIFO;
case V_TYPE_LINK:
return TYPE_LINK;
case V_TYPE_SOCKET:
return TYPE_SOCKET;
default:
return 0;
}
}
#endif
+58
View File
@@ -0,0 +1,58 @@
#include <kernel/syscalls.h>
#include <kernel/file.h>
#include <kernel/vmm.h>
#include <errno.h>
#include <kernel/alloc.h>
syscallret_t syscall_getdents(context_t *, int dirfd, void *ubuffer, size_t readmax) {
syscallret_t ret = {
.ret = -1
};
if (ubuffer > USERSPACE_END) {
ret.errno = EFAULT;
return ret;
}
size_t count = readmax / sizeof(dent_t);
if (count == 0) {
ret.errno = EINVAL;
return ret;
}
dent_t *buffer = alloc(readmax);
if (buffer == NULL) {
ret.errno = ENOMEM;
return ret;
}
file_t *fd = fd_get(dirfd);
if (fd == NULL) {
free(buffer);
ret.errno = EBADF;
return ret;
}
if (fd->vnode->type != V_TYPE_DIR) {
ret.errno = ENOTDIR;
goto cleanup;
}
ret.errno = VOP_GETDENTS(fd->vnode, buffer, count, fd->offset, &ret.ret);
if (ret.errno)
goto cleanup;
fd->offset += ret.ret;
ret.ret *= sizeof(dent_t);
// TODO safe memcpy
memcpy(ubuffer, buffer, ret.ret);
cleanup:
free(buffer);
fd_release(fd);
return ret;
}
+18 -4
View File
@@ -133,10 +133,10 @@ index 0000000..e5b087a
+
diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
new file mode 100644
index 0000000..601407e
index 0000000..c177a55
--- /dev/null
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
@@ -0,0 +1,193 @@
@@ -0,0 +1,206 @@
+#include <bits/ensure.h>
+#include <mlibc/debug.hpp>
+#include <mlibc/all-sysdeps.hpp>
@@ -192,6 +192,15 @@ index 0000000..601407e
+ return 0;
+ }
+
+ int sys_read_entries(int handle, void *buffer, size_t max_size, size_t *bytes_read) {
+ long ret;
+ long err = syscall(SYSCALL_GETDENTS, &ret, handle, (uint64_t)buffer, max_size);
+ if (err)
+ return err;
+ *bytes_read = ret;
+ return err;
+ }
+
+ int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid) {
+ long ret;
+ long err = syscall(SYSCALL_WAITPID, &ret, pid, (uint64_t)status, flags);
@@ -280,6 +289,10 @@ index 0000000..601407e
+ return 0;
+ };
+
+ int sys_open_dir(const char *path, int *handle) {
+ return sys_open(path, O_DIRECTORY, 0, handle);
+ }
+
+ int sys_read(int fd, void *buff, size_t count, ssize_t *bytes_read) {
+ long readc;
+ long error = syscall(SYSCALL_READ, &readc, fd, (uint64_t)buff, count);
@@ -349,10 +362,10 @@ index 0000000..990eca0
+#endif
diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
new file mode 100644
index 0000000..1562c23
index 0000000..6b0e993
--- /dev/null
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
@@ -0,0 +1,39 @@
@@ -0,0 +1,40 @@
+#ifndef _SYSCALL_H_INCLUDE
+#define _SYSCALL_H_INCLUDE
+
@@ -372,6 +385,7 @@ index 0000000..1562c23
+#define SYSCALL_EXIT 13
+#define SYSCALL_WAITPID 14
+#define SYSCALL_MUNMAP 15
+#define SYSCALL_GETDENTS 16
+
+#include <stddef.h>
+#include <stdint.h>