mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
syscalls: openat
This commit is contained in:
@@ -31,7 +31,8 @@ extern syscall_munmap
|
|||||||
extern syscall_umask
|
extern syscall_umask
|
||||||
extern syscall_poll
|
extern syscall_poll
|
||||||
extern syscall_fchmodat
|
extern syscall_fchmodat
|
||||||
func_count equ 30
|
extern syscall_openat
|
||||||
|
func_count equ 31
|
||||||
|
|
||||||
|
|
||||||
func_table:
|
func_table:
|
||||||
@@ -65,6 +66,7 @@ func_table:
|
|||||||
dq syscall_umask
|
dq syscall_umask
|
||||||
dq syscall_poll
|
dq syscall_poll
|
||||||
dq syscall_fchmodat
|
dq syscall_fchmodat
|
||||||
|
dq syscall_openat
|
||||||
section .text
|
section .text
|
||||||
global asm_syscall_entry
|
global asm_syscall_entry
|
||||||
|
|
||||||
|
|||||||
+32
-4
@@ -8,8 +8,7 @@
|
|||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
syscallret syscall_openat(int dirfd, const char* pathname, int flags, mode_t mode){
|
||||||
syscallret syscall_open(const char* pathname, int flags, mode_t mode){
|
|
||||||
syscallret retv;
|
syscallret retv;
|
||||||
retv.ret = -1;
|
retv.ret = -1;
|
||||||
|
|
||||||
@@ -39,6 +38,26 @@ syscallret syscall_open(const char* pathname, int flags, mode_t mode){
|
|||||||
return retv;
|
return retv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd_t* targfd;
|
||||||
|
dirnode_t* target;
|
||||||
|
|
||||||
|
if(dirfd != AT_FDCWD){
|
||||||
|
|
||||||
|
err = fd_access(&proc->fdtable, &targfd, dirfd);
|
||||||
|
|
||||||
|
if(err){
|
||||||
|
retv.errno = err;
|
||||||
|
free(name);
|
||||||
|
fd_release(fd);
|
||||||
|
fd_free(&proc->fdtable, fd);
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = targfd->node;
|
||||||
|
|
||||||
|
}
|
||||||
|
else target = proc->cwd;
|
||||||
|
|
||||||
fd->flags = flags + 1; // 1 is added to make O_RDONLY etc easier to lookup
|
fd->flags = flags + 1; // 1 is added to make O_RDONLY etc easier to lookup
|
||||||
fd->offset = 0;
|
fd->offset = 0;
|
||||||
|
|
||||||
@@ -47,8 +66,8 @@ syscallret syscall_open(const char* pathname, int flags, mode_t mode){
|
|||||||
retry:
|
retry:
|
||||||
|
|
||||||
size_t ret = vfs_open(&file,
|
size_t ret = vfs_open(&file,
|
||||||
*name == '/' ? proc->root : proc->cwd,
|
*name == '/' ? proc->root : target,
|
||||||
*name == '/' ? name + 1 : name
|
name
|
||||||
);
|
);
|
||||||
|
|
||||||
if(ret == ENOENT && (flags & O_CREAT)){
|
if(ret == ENOENT && (flags & O_CREAT)){
|
||||||
@@ -93,9 +112,18 @@ syscallret syscall_open(const char* pathname, int flags, mode_t mode){
|
|||||||
if(file)
|
if(file)
|
||||||
vfs_close(file);
|
vfs_close(file);
|
||||||
|
|
||||||
|
if(dirfd != AT_FDCWD)
|
||||||
|
fd_release(targfd);
|
||||||
|
|
||||||
fd_release(fd);
|
fd_release(fd);
|
||||||
fd_free(&proc->fdtable, fd);
|
fd_free(&proc->fdtable, fd);
|
||||||
free(name);
|
free(name);
|
||||||
return retv;
|
return retv;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// kept so no ABI breaks happen
|
||||||
|
|
||||||
|
syscallret syscall_open(const char* pathname, int flags, mode_t mode){
|
||||||
|
return syscall_openat(AT_FDCWD, pathname, flags, mode);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user