diff --git a/src/filesys/sysfile.c b/src/filesys/sysfile.c index 998da9f..4ad2997 100644 --- a/src/filesys/sysfile.c +++ b/src/filesys/sysfile.c @@ -210,3 +210,20 @@ syscall_fstat(void) return SYS_FAIL_RC; return 0; } + +/** int32_t seek(int32_t fd, uint32_t offset); */ +int32_t +syscall_seek(void) +{ + int32_t fd; + uint32_t offset; + + if (!sysarg_get_int(0, &fd)) + return SYS_FAIL_RC; + if (!sysarg_get_uint(1, &offset)) + return SYS_FAIL_RC; + + if (!filesys_seek(fd, offset)) + return SYS_FAIL_RC; + return 0; +} diff --git a/src/filesys/sysfile.h b/src/filesys/sysfile.h index 971c0aa..1e66be5 100644 --- a/src/filesys/sysfile.h +++ b/src/filesys/sysfile.h @@ -38,6 +38,7 @@ int32_t syscall_chdir(); int32_t syscall_getcwd(); int32_t syscall_exec(); int32_t syscall_fstat(); +int32_t syscall_seek(); #endif diff --git a/src/filesys/vsfs.c b/src/filesys/vsfs.c index 84ddc23..8bf66fd 100644 --- a/src/filesys/vsfs.c +++ b/src/filesys/vsfs.c @@ -679,6 +679,30 @@ filesys_fstat(int8_t fd, file_stat_t *stat) } +/** Seek to absolute file offset. */ +bool +filesys_seek(int8_t fd, size_t offset) +{ + file_t *file = _find_process_file(fd); + if (file == NULL) { + warn("seek: cannot find file for fd %d", fd); + return false; + } + + inode_lock(file->inode); + size_t filesize = file->inode->d_inode.size; + inode_unlock(file->inode); + + if (offset > filesize) { + warn("seek: offset %lu beyond filesize %lu", offset, filesize); + return false; + } + + file->offset = offset; + return true; +} + + /** Flush the in-memory modified bitmap block to disk. */ bool inode_bitmap_update(uint32_t slot_no) diff --git a/src/filesys/vsfs.h b/src/filesys/vsfs.h index 3d2fb5e..1c38076 100644 --- a/src/filesys/vsfs.h +++ b/src/filesys/vsfs.h @@ -130,6 +130,8 @@ bool filesys_exec(char *path, char **argv); bool filesys_fstat(int8_t fd, file_stat_t *stat); +bool filesys_seek(int8_t fd, size_t offset); + bool inode_bitmap_update(uint32_t slot_no); bool data_bitmap_update(uint32_t slot_no); diff --git a/src/interrupt/syscall.c b/src/interrupt/syscall.c index 8b70385..91672a7 100644 --- a/src/interrupt/syscall.c +++ b/src/interrupt/syscall.c @@ -47,7 +47,8 @@ static syscall_t syscall_handlers[] = { [SYSCALL_CHDIR] syscall_chdir, [SYSCALL_GETCWD] syscall_getcwd, [SYSCALL_EXEC] syscall_exec, - [SYSCALL_FSTAT] syscall_fstat + [SYSCALL_FSTAT] syscall_fstat, + [SYSCALL_SEEK] syscall_seek }; #define NUM_SYSCALLS ((int32_t) (sizeof(syscall_handlers) / sizeof(syscall_t))) diff --git a/src/interrupt/syscall.h b/src/interrupt/syscall.h index 27a7968..8414335 100644 --- a/src/interrupt/syscall.h +++ b/src/interrupt/syscall.h @@ -38,6 +38,7 @@ #define SYSCALL_GETCWD 18 #define SYSCALL_EXEC 19 #define SYSCALL_FSTAT 20 +#define SYSCALL_SEEK 21 /** diff --git a/user/lib/syscall.h b/user/lib/syscall.h index 893b25c..be9dd73 100644 --- a/user/lib/syscall.h +++ b/user/lib/syscall.h @@ -74,6 +74,7 @@ extern int32_t chdir(char *path); extern int32_t getcwd(char *buf, uint32_t limit); extern int32_t exec(char *path, char **argv); extern int32_t fstat(int32_t fd, file_stat_t *stat); +extern int32_t seek(int32_t fd, uint32_t offset); #endif diff --git a/user/lib/syscall.s b/user/lib/syscall.s index fcbddf1..1ee6594 100644 --- a/user/lib/syscall.s +++ b/user/lib/syscall.s @@ -40,3 +40,4 @@ SYSCALL_LIBGEN chdir, SYSCALL_CHDIR SYSCALL_LIBGEN getcwd, SYSCALL_GETCWD SYSCALL_LIBGEN exec, SYSCALL_EXEC SYSCALL_LIBGEN fstat, SYSCALL_FSTAT +SYSCALL_LIBGEN seek, SYSCALL_SEEK diff --git a/user/lib/syslist.s b/user/lib/syslist.s index d8319ee..968ff25 100644 --- a/user/lib/syslist.s +++ b/user/lib/syslist.s @@ -31,3 +31,4 @@ SYSCALL_CHDIR = 17 SYSCALL_GETCWD = 18 SYSCALL_EXEC = 19 SYSCALL_FSTAT = 20 +SYSCALL_SEEK = 21 diff --git a/user/put.c b/user/put.c index 16feb55..86ba13e 100644 --- a/user/put.c +++ b/user/put.c @@ -44,7 +44,6 @@ _open_writable_file(char *path, bool overwrite) /** If not overwriting, seek to current file end. */ if (!overwrite) { - assert(stat.size >= 0); int ret = seek(fd, stat.size); if (ret != 0) { warn("put: cannot seek to offset %lu", stat.size); @@ -72,10 +71,11 @@ _file_put_str(char *path, char *str, size_t len, bool overwrite, bool newline) } /** If putting newline after string. */ - if (newline) + if (newline) { bytes_written = write(fd, "\n", 1); - if (bytes_written != 1) - warn("put: newline written %lu != 1", bytes_written); + if (bytes_written != 1) + warn("put: newline written %lu != 1", bytes_written); + } close(fd); } diff --git a/wiki b/wiki index 716b0c6..668fd5e 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 716b0c601196aa8dff2d000c6b848476efb14ffe +Subproject commit 668fd5e003e12cb470fa303cbb117dd66dd91e80