mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
syscalls: getdirent
This commit is contained in:
@@ -21,7 +21,8 @@ extern syscall_dup
|
||||
extern syscall_dup2
|
||||
extern syscall_fcntl
|
||||
extern syscall_getpid
|
||||
func_count equ 20
|
||||
extern syscall_getdirent
|
||||
func_count equ 21
|
||||
|
||||
|
||||
func_table:
|
||||
@@ -45,6 +46,7 @@ func_table:
|
||||
dq syscall_dup2
|
||||
dq syscall_fcntl
|
||||
dq syscall_getpid
|
||||
dq syscall_getdirent
|
||||
section .text
|
||||
global asm_syscall_entry
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#include <kernel/syscalls.h>
|
||||
#include <dirent.h>
|
||||
#include <arch/cls.h>
|
||||
#include <sys/stat.h>
|
||||
#include <kernel/vmm.h>
|
||||
|
||||
syscallret syscall_getdirent(int ifd, void* buff, size_t max_size){
|
||||
syscallret retv;
|
||||
retv.ret = -1;
|
||||
|
||||
if(buff > USER_SPACE_END){
|
||||
retv.errno = EFAULT;
|
||||
return retv;
|
||||
}
|
||||
|
||||
size_t readc = max_size / sizeof(dent_t);
|
||||
|
||||
if(readc == 0){
|
||||
retv.errno = EINVAL;
|
||||
return retv;
|
||||
}
|
||||
|
||||
fd_t* fd;
|
||||
|
||||
retv.errno = fd_access(&arch_getcls()->thread->proc->fdtable, &fd, ifd);
|
||||
|
||||
if(retv.errno)
|
||||
return retv;
|
||||
|
||||
if(GETTYPE(fd->node->st.st_mode) != TYPE_DIR){
|
||||
retv.errno = ENOTDIR;
|
||||
fd_release(fd);
|
||||
return retv;
|
||||
}
|
||||
|
||||
dent_t kbuff[readc];
|
||||
|
||||
retv.errno = vfs_getdirent(fd->node, kbuff, readc, fd->offset, &retv.ret);
|
||||
|
||||
|
||||
fd->offset += retv.ret;
|
||||
|
||||
retv.ret *= sizeof(dent_t);
|
||||
|
||||
memcpy(buff, kbuff, retv.ret); // XXX use user memcpy
|
||||
|
||||
fd_release(fd);
|
||||
|
||||
return retv;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user