diff --git a/src/arch/x86_64/syscall.asm b/src/arch/x86_64/syscall.asm index e44e6b06..995f38c7 100644 --- a/src/arch/x86_64/syscall.asm +++ b/src/arch/x86_64/syscall.asm @@ -10,7 +10,8 @@ extern syscall_read extern syscall_lseek extern syscall_close extern syscall_isatty -func_count equ 9 +extern syscall_write +func_count equ 10 func_table: @@ -23,6 +24,7 @@ func_table: dq syscall_lseek dq syscall_close dq syscall_isatty + dq syscall_write section .text global asm_syscall_entry diff --git a/src/sys/sched/scheduler.c b/src/sys/sched/scheduler.c index 738aaae3..16b8d1b3 100644 --- a/src/sys/sched/scheduler.c +++ b/src/sys/sched/scheduler.c @@ -327,8 +327,8 @@ void sched_runinit(){ } stdinfd->offset = stdoutfd->offset = stderrfd->offset = 0; - stdinfd->flags = O_RDONLY; - stdoutfd->flags = stderrfd->flags = O_WRONLY; + stdinfd->flags = O_RDONLY + 1; + stdoutfd->flags = stderrfd->flags = O_WRONLY + 1; vnode_t* node; ret = vfs_open(&node, vfs_root(), "sbin/init"); diff --git a/src/sys/syscalls/lseek.c b/src/sys/syscalls/lseek.c index 698b8998..11046956 100644 --- a/src/sys/syscalls/lseek.c +++ b/src/sys/syscalls/lseek.c @@ -19,7 +19,7 @@ syscallret syscall_lseek(int ifd, off_t offset, int whence){ 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); retv.errno = EBADF; return retv; diff --git a/src/sys/syscalls/write.c b/src/sys/syscalls/write.c new file mode 100644 index 00000000..3a73a489 --- /dev/null +++ b/src/sys/syscalls/write.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} +