Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/syscall/lseek.c
2093 views
1
#include <types.h>
2
#include <lib.h>
3
#include <proc.h>
4
#include <file.h>
5
#include <vnode.h>
6
#include <vfs.h>
7
#include <stat.h>
8
#include <kern/fcntl.h>
9
#include <kern/seek.h>
10
#include <kern/errno.h>
11
#include <current.h>
12
#include <syscall.h>
13
14
int
15
sys_lseek( int fd, off_t offset, int whence, int64_t *retval ) {
16
struct proc *p = NULL;
17
struct file *f = NULL;
18
int err;
19
struct stat st;
20
off_t new_offset;
21
22
KASSERT( curthread != NULL );
23
KASSERT( curthread->td_proc != NULL );
24
25
p = curthread->td_proc;
26
27
//try to open the file
28
err = file_get( p, fd, &f );
29
if( err )
30
return err;
31
32
//depending on whence, seek to appropriate location
33
switch( whence ) {
34
case SEEK_SET:
35
new_offset = offset;
36
break;
37
38
case SEEK_CUR:
39
new_offset = f->f_offset + offset;
40
break;
41
42
case SEEK_END:
43
//if it is SEEK_END, we use VOP_STAT to figure out
44
//the size of the file, and set the offset to be that size.
45
err = VOP_STAT( f->f_vnode, &st );
46
if( err ) {
47
F_UNLOCK( f );
48
return err;
49
}
50
51
//set the offet to the filesize.
52
new_offset = st.st_size + offset;
53
break;
54
default:
55
F_UNLOCK( f );
56
return EINVAL;
57
}
58
59
//use VOP_TRYSEEK to verify whether the desired
60
//seeking location is proper.
61
err = VOP_TRYSEEK( f->f_vnode, new_offset );
62
if( err ) {
63
F_UNLOCK( f );
64
return err;
65
}
66
67
//adjust the seek.
68
f->f_offset = new_offset;
69
*retval = new_offset;
70
F_UNLOCK( f );
71
return 0;
72
}
73
74