mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
write system call
This commit is contained in:
@@ -10,7 +10,8 @@ extern syscall_read
|
|||||||
extern syscall_lseek
|
extern syscall_lseek
|
||||||
extern syscall_close
|
extern syscall_close
|
||||||
extern syscall_isatty
|
extern syscall_isatty
|
||||||
func_count equ 9
|
extern syscall_write
|
||||||
|
func_count equ 10
|
||||||
|
|
||||||
|
|
||||||
func_table:
|
func_table:
|
||||||
@@ -23,6 +24,7 @@ func_table:
|
|||||||
dq syscall_lseek
|
dq syscall_lseek
|
||||||
dq syscall_close
|
dq syscall_close
|
||||||
dq syscall_isatty
|
dq syscall_isatty
|
||||||
|
dq syscall_write
|
||||||
section .text
|
section .text
|
||||||
global asm_syscall_entry
|
global asm_syscall_entry
|
||||||
|
|
||||||
|
|||||||
@@ -327,8 +327,8 @@ void sched_runinit(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
stdinfd->offset = stdoutfd->offset = stderrfd->offset = 0;
|
stdinfd->offset = stdoutfd->offset = stderrfd->offset = 0;
|
||||||
stdinfd->flags = O_RDONLY;
|
stdinfd->flags = O_RDONLY + 1;
|
||||||
stdoutfd->flags = stderrfd->flags = O_WRONLY;
|
stdoutfd->flags = stderrfd->flags = O_WRONLY + 1;
|
||||||
|
|
||||||
vnode_t* node;
|
vnode_t* node;
|
||||||
ret = vfs_open(&node, vfs_root(), "sbin/init");
|
ret = vfs_open(&node, vfs_root(), "sbin/init");
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ syscallret syscall_lseek(int ifd, off_t offset, int whence){
|
|||||||
|
|
||||||
spinlock_acquire(&proc->fdlock);
|
spinlock_acquire(&proc->fdlock);
|
||||||
|
|
||||||
if(proc->fdcount <= ifd || fd->node == NULL || (fd->flags & FD_FLAGS_READ) == 0){
|
if(proc->fdcount <= ifd || fd->node == NULL){
|
||||||
spinlock_release(&proc->fdlock);
|
spinlock_release(&proc->fdlock);
|
||||||
retv.errno = EBADF;
|
retv.errno = EBADF;
|
||||||
return retv;
|
return retv;
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#include <kernel/syscalls.h>
|
||||||
|
#include <kernel/fd.h>
|
||||||
|
#include <kernel/alloc.h>
|
||||||
|
#include <kernel/vfs.h>
|
||||||
|
#include <arch/cls.h>
|
||||||
|
#include <kernel/sched.h>
|
||||||
|
#include <arch/spinlock.h>
|
||||||
|
#include <kernel/vmm.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
syscallret syscall_write(int ifd, void* buff, size_t count){
|
||||||
|
|
||||||
|
// TODO the other flags
|
||||||
|
|
||||||
|
syscallret retv;
|
||||||
|
retv.ret = -1;
|
||||||
|
|
||||||
|
if(buff > USER_SPACE_END){
|
||||||
|
retv.errno = EFAULT;
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_WRITE) == 0){
|
||||||
|
spinlock_release(&proc->fdlock);
|
||||||
|
retv.errno = EBADF;
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_acquire(&fd->lock);
|
||||||
|
spinlock_release(&proc->fdlock);
|
||||||
|
|
||||||
|
void* kbuff = alloc(count);
|
||||||
|
|
||||||
|
if(!kbuff){
|
||||||
|
spinlock_release(&fd->lock);
|
||||||
|
retv.errno = ENOMEM;
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(kbuff, buff, count); // XXX use a more proper user copy
|
||||||
|
|
||||||
|
if(fd->flags & O_APPEND)
|
||||||
|
fd->offset = fd->node->st.st_size;
|
||||||
|
|
||||||
|
int err;
|
||||||
|
size_t writec = vfs_write(&err, fd->node, kbuff, count, fd->offset);
|
||||||
|
|
||||||
|
|
||||||
|
if(err){
|
||||||
|
retv.errno = err;
|
||||||
|
goto _ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd->offset += writec;
|
||||||
|
|
||||||
|
retv.errno = 0;
|
||||||
|
retv.ret = writec;
|
||||||
|
|
||||||
|
_ret:
|
||||||
|
spinlock_release(&fd->lock);
|
||||||
|
free(kbuff);
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user