diff options
Diffstat (limited to 'src/sys/os')
-rw-r--r-- | src/sys/os/os_filedes.c | 53 | ||||
-rw-r--r-- | src/sys/os/vfs_namei.c | 1 | ||||
-rw-r--r-- | src/sys/os/vfs_subr.c | 20 |
3 files changed, 74 insertions, 0 deletions
diff --git a/src/sys/os/os_filedes.c b/src/sys/os/os_filedes.c index ca56fc3..36748a6 100644 --- a/src/sys/os/os_filedes.c +++ b/src/sys/os/os_filedes.c @@ -359,6 +359,44 @@ read(int fd, void *buf, size_t count) return retval; } +off_t +lseek(int fd, off_t offset, int whence) +{ + struct filedesc *fdp; + struct proc *self = proc_self(); + struct vattr attr; + int error; + + if (fd < 0) { + return -EBADF; + } + + fdp = fd_get(self, fd); + if (fdp == NULL) { + return -EBADF; + } + + /* Could not get vnode attributes */ + error = vop_getattr(fdp->vp, &attr); + if (error < 0) { + return 0; + } + + switch (whence) { + case SEEK_SET: + fdp->off = offset; + break; + case SEEK_CUR: + fdp->off += offset; + break; + case SEEK_END: + fdp->off = attr.size; + break; + } + + return fdp->off; +} + /* * ARG0: Path * ARG1: Mode @@ -378,3 +416,18 @@ sys_open(struct syscall_args *scargs) return fd_open(pathbuf, mode); } + +/* + * ARG0: Fd + * ARG1: Offset + * ARG2: Whence + */ +scret_t +sys_lseek(struct syscall_args *scargs) +{ + int fd = SCARG(scargs, int, 0); + off_t off = SCARG(scargs, off_t, 1); + int whence = SCARG(scargs, int, 2); + + return lseek(fd, off, whence); +} diff --git a/src/sys/os/vfs_namei.c b/src/sys/os/vfs_namei.c index d417db8..7814181 100644 --- a/src/sys/os/vfs_namei.c +++ b/src/sys/os/vfs_namei.c @@ -149,6 +149,7 @@ namei(struct nameidata *ndp) nd_create.path = namebuf; create.ndp = &nd_create; + create.vtype = VTYPE_FILE; error = vops->create(&create); if (error < 0) return error; diff --git a/src/sys/os/vfs_subr.c b/src/sys/os/vfs_subr.c index adfcffb..2ae18af 100644 --- a/src/sys/os/vfs_subr.c +++ b/src/sys/os/vfs_subr.c @@ -246,3 +246,23 @@ vop_create(struct vnode *vp, struct nameidata *ndp) args.ndp = ndp; return vops->create(&args); } + +int +vop_getattr(struct vnode *vp, struct vattr *res) +{ + struct vop *vops; + + if (vp == NULL || res == NULL) { + return -EINVAL; + } + + if ((vops = vp->vops) == NULL) { + return -EIO; + } + + if (vops->getattr == NULL) { + return -EIO; + } + + return vops->getattr(vp, res); +} |