syscall: openat

This commit is contained in:
Matheus
2023-05-09 23:25:29 -03:00
parent f56a0f27d7
commit 4cfb83f4fe
3 changed files with 112 additions and 6 deletions
+3 -1
View File
@@ -1,11 +1,13 @@
section .rodata
extern syscall_print
extern syscall_mmap
extern syscall_openat
syscalltab:
dq syscall_print
dq syscall_mmap
dq syscall_openat
syscallcount equ 2
syscallcount equ 3
section .text
global arch_syscall_entry
; on entry:
+98
View File
@@ -0,0 +1,98 @@
#include <kernel/syscalls.h>
#include <kernel/file.h>
#include <kernel/abi.h>
#include <kernel/alloc.h>
#include <errno.h>
#include <logging.h>
syscallret_t syscall_openat(context_t *context, int dirfd, const char *path, int flags, mode_t mode) {
syscallret_t ret = {
.ret = -1,
.errno = 0
};
// transform O_RDONLY, O_WRONLY, O_RDWR into FILE_READ and FILE_WRITE
++flags;
__assert((~FILE_KNOWN_FLAGS & flags) == 0);
vnode_t *dirnode = NULL;
file_t *dirfile;
size_t pathsize = strlen(path); // TODO u_strlen
char *pathbuf = alloc(pathsize + 1);
strcpy(pathbuf, path); // TODO u_strcpy
if (*pathbuf == '/') {
dirnode = sched_getroot();
dirfile = NULL;
} else if (dirfd == AT_FDCWD) {
dirnode = sched_getcwd();
dirfile = NULL;
} else {
dirfile = fd_get(dirfd);
if (dirfile == NULL) {
ret.errno = EBADF;
goto cleanup;
}
dirnode = dirfile->vnode;
if (dirnode->type != V_TYPE_DIR) {
ret.errno = ENOTDIR;
goto cleanup;
}
}
// TODO pass CLOEXEC to fd
file_t *newfile = NULL;
int newfd;
ret.errno = fd_new(0, &newfile, &newfd);
if (ret.errno)
goto cleanup;
vnode_t *vnode = NULL;
ret.errno = vfs_open(dirnode, pathbuf, fileflagstovnodeflags(flags), &vnode);
if (ret.errno)
goto cleanup;
vattr_t attr;
VOP_LOCK(vnode);
ret.errno = VOP_GETATTR(vnode, &attr, &_cpu()->thread->proc->cred);
VOP_UNLOCK(vnode);
if (ret.errno)
goto cleanup;
// node refcount is already increased by open
newfile->vnode = vnode;
newfile->flags = flags;
newfile->offset = 0;
newfile->mode = attr.mode;
ret.errno = 0;
ret.ret = newfd;
cleanup:
if (vnode && ret.errno) {
vfs_close(vnode, fileflagstovnodeflags(flags));
VOP_RELEASE(vnode);
}
if (newfile) {
if (ret.errno) {
__assert(fd_close(newfd) == 0);
} else {
fd_release(newfile);
}
}
if (pathbuf)
free(pathbuf);
if (dirfile) {
fd_release(dirfile);
} else if (dirnode){
VOP_RELEASE(dirnode);
}
return ret;
}
+11 -5
View File
@@ -113,10 +113,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..4d9555e
index 0000000..6715503
--- /dev/null
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
@@ -0,0 +1,138 @@
@@ -0,0 +1,143 @@
+#include <bits/ensure.h>
+#include <mlibc/debug.hpp>
+#include <mlibc/all-sysdeps.hpp>
@@ -218,7 +218,12 @@ index 0000000..4d9555e
+ }
+
+ int sys_open(const char *pathname, int flags, mode_t mode, int *fd) {
+ return ENOSYS;
+ long ret;
+ long err = syscall(SYSCALL_OPENAT, &ret, AT_FDCWD, (uint64_t)pathname, flags, mode);
+ if (err)
+ return err;
+ *fd = ret;
+ return 0;
+ };
+ int sys_read(int fd, void *buff, size_t count, ssize_t *bytes_read) {
+ return ENOSYS;
@@ -274,15 +279,16 @@ 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..8f1ee3c
index 0000000..6ef92cd
--- /dev/null
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
@@ -0,0 +1,25 @@
@@ -0,0 +1,26 @@
+#ifndef _SYSCALL_H_INCLUDE
+#define _SYSCALL_H_INCLUDE
+
+#define SYSCALL_PRINT 0
+#define SYSCALL_MMAP 1
+#define SYSCALL_OPENAT 2
+
+#include <stddef.h>
+#include <stdint.h>