summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/include/sys/filedesc.h7
-rw-r--r--sys/kern/kern_descrip.c35
2 files changed, 42 insertions, 0 deletions
diff --git a/sys/include/sys/filedesc.h b/sys/include/sys/filedesc.h
index 60b638e..5f7e4e3 100644
--- a/sys/include/sys/filedesc.h
+++ b/sys/include/sys/filedesc.h
@@ -33,7 +33,13 @@
#include <sys/types.h>
#if defined(_KERNEL)
#include <sys/vnode.h>
+#include <sys/syscall.h>
#include <sys/spinlock.h>
+#include <sys/syscall.h>
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
struct filedesc {
int fdno;
@@ -51,6 +57,7 @@ int fd_write(unsigned int fd, void *buf, size_t count);
int fd_alloc(struct filedesc **fd_out);
int fd_open(const char *pathname, int flags);
+off_t fd_seek(int fildes, off_t offset, int whence);
int fd_dup(int fd);
struct filedesc *fd_get(unsigned int fdno);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 1992d46..1737b53 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -296,3 +296,38 @@ fd_dup(int fd)
new_desc->vp = tmp->vp;
return new_desc->fdno;
}
+
+off_t
+fd_seek(int fildes, off_t offset, int whence)
+{
+ struct filedesc *tmp;
+ struct vattr attr;
+ struct vop_getattr_args getattr_args;
+
+ tmp = fd_get(fildes);
+ if (tmp == NULL) {
+ return -EBADF;
+ }
+
+ getattr_args.vp = tmp->vp;
+ getattr_args.res = &attr;
+ if ((vfs_vop_getattr(tmp->vp, &getattr_args)) < 0) {
+ return -EPIPE;
+ }
+
+ switch (whence) {
+ case SEEK_SET:
+ tmp->offset = offset;
+ break;
+ case SEEK_CUR:
+ tmp->offset += offset;
+ break;
+ case SEEK_END:
+ tmp->offset = attr.size + offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}