Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/syscall/open.c
2093 views
1
#include <types.h>
2
#include <lib.h>
3
#include <kern/errno.h>
4
#include <syscall.h>
5
#include <file.h>
6
#include <filedesc.h>
7
#include <copyinout.h>
8
#include <kern/fcntl.h>
9
#include <stat.h>
10
#include <vfs.h>
11
#include <current.h>
12
13
//check to see if the given flags are valid.
14
//valid flags consist of exactly one of O_RDONLY/O_WRONLY/O_RDWR.
15
static
16
bool
17
valid_flags( int flags ) {
18
int count = 0;
19
int accmode = flags & O_ACCMODE;
20
21
if( accmode == O_RDWR )
22
++count;
23
24
if( accmode == O_RDONLY )
25
++count;
26
27
if( accmode == O_WRONLY )
28
++count;
29
30
return count == 1;
31
}
32
33
//kernel version of the open() systemcall.
34
int
35
___open( struct proc *p, char *path, int flags, int *retval ) {
36
struct vnode *vn = NULL;
37
int err;
38
struct file *f = NULL;
39
struct stat st;
40
41
//attempt to open the file
42
err = vfs_open( path, flags, 0, &vn );
43
if( err )
44
return err;
45
46
//atempt to create the file object
47
err = file_create( vn, flags, &f );
48
if( err ) {
49
vfs_close( vn );
50
return err;
51
}
52
53
//if we have O_APPEND, we must set the offset
54
//to be the file size.
55
if( flags & O_APPEND ) {
56
err = VOP_STAT( f->f_vnode, &st );
57
if( err ) {
58
vfs_close( vn );
59
file_destroy( f );
60
return err;
61
}
62
63
f->f_offset = st.st_size;
64
}
65
66
//lock the file so we can safely modify
67
F_LOCK( f );
68
69
//we now need to find a spot inside the process' filetable
70
//so we can store our new file
71
err = fd_attach( p->p_fd, f, retval );
72
if( err ) {
73
F_UNLOCK( f );
74
vfs_close( vn );
75
file_destroy( f );
76
return err;
77
}
78
79
//increase both references counts
80
f->f_refcount++;
81
VOP_INCREF( f->f_vnode );
82
83
//we are done if the file, unlock it
84
F_UNLOCK( f );
85
return 0;
86
87
}
88
89
int
90
sys_open( userptr_t upath, int flags, int *retval ) {
91
char k_filename[MAX_FILE_NAME];
92
int err;
93
struct proc *p;
94
95
//make sure the current thread is not null
96
//and that we have a process associated with it
97
KASSERT( curthread != NULL );
98
KASSERT( curthread->td_proc != NULL );
99
100
p = curthread->td_proc;
101
102
//check if we have valid flags
103
if( !valid_flags( flags ) )
104
return EINVAL;
105
106
//copy the path from userland into kernel-land
107
err = copyinstr( upath, k_filename, sizeof( k_filename ), NULL );
108
109
//if we couldn't copy the file name, we probably have an I/O error
110
//simply return that error code
111
if( err )
112
return err;
113
114
//delegate the actual opening to another function.
115
return ___open( p, k_filename, flags, retval );
116
}
117
118