lseek syscall

This commit is contained in:
Matheus
2022-08-19 20:26:37 -03:00
parent 6350621f7d
commit d8d5f44d8e
2 changed files with 79 additions and 0 deletions
+2
View File
@@ -7,6 +7,7 @@ extern syscall_arch_ctl
extern syscall_gettid
extern syscall_open
extern syscall_read
extern syscall_lseek
func_count equ 6
@@ -17,6 +18,7 @@ func_table:
dq syscall_gettid
dq syscall_open
dq syscall_read
dq syscall_lseek
section .text
global asm_syscall_entry
+77
View File
@@ -0,0 +1,77 @@
#include <kernel/syscalls.h>
#include <arch/cls.h>
#include <kernel/fd.h>
#include <arch/spinlock.h>
#include <sys/stat.h>
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
syscallret syscall_lseek(int ifd, off_t offset, int whence){
syscallret retv;
retv.ret = -1;
proc_t* proc = arch_getcls()->thread->proc;
fd_t* fd = proc->fds + ifd;
spinlock_acquire(&proc->fdlock);
if(proc->fdcount <= ifd || fd->node == NULL || (fd->flags & FD_FLAGS_READ) == 0){
spinlock_release(&proc->fdlock);
retv.errno = EBADF;
return retv;
}
spinlock_acquire(&fd->lock);
spinlock_release(&proc->fdlock);
int type = GETTYPE(fd->node->st.st_mode);
if(type == TYPE_SOCKET || type == TYPE_FIFO){
retv.errno = ESPIPE;
goto _ret;
}
off_t newoffset = fd->offset;
size_t fsize = fd->node->st.st_size;
switch(whence){
case SEEK_SET:
if(offset < 0 || offset > fsize){
retv.errno = EINVAL;
goto _ret;
}
newoffset = offset;
break;
case SEEK_CUR:
newoffset += offset;
if(newoffset < 0 || newoffset > fsize){
retv.errno = EINVAL;
goto _ret;
}
if(newoffset < offset){
retv.errno = EOVERFLOW;
goto _ret;
}
break;
case SEEK_END:
newoffset = fsize;
break;
default:
retv.errno = EINVAL;
goto _ret;
}
fd->offset = newoffset;
retv.errno = 0;
retv.ret = newoffset;
_ret:
spinlock_release(&fd->lock);
return retv;
}