Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/io/filedesc.c
2093 views
1
#include <types.h>
2
#include <lib.h>
3
#include <kern/errno.h>
4
#include <filedesc.h>
5
6
//scan over the given file descriptor table
7
//and store the file in a free location, if possible
8
int
9
fd_attach( struct filedesc *fdesc, struct file *f, int *fd ) {
10
int i = 0;
11
12
//lock the file descriptor table
13
FD_LOCK( fdesc );
14
15
//for each possible spot
16
for( i = 0; i < MAX_OPEN_FILES; ++i ) {
17
if( fdesc->fd_ofiles[i] == NULL ) {
18
fdesc->fd_ofiles[i] = f;
19
fdesc->fd_nfiles++;
20
*fd = i;
21
FD_UNLOCK( fdesc );
22
return 0;
23
}
24
}
25
FD_UNLOCK( fdesc );
26
return ENFILE;
27
}
28
29
//detaches the given filedescriptor from the given filetable
30
void
31
fd_detach( struct filedesc *fdesc, int fd ) {
32
FD_LOCK( fdesc );
33
fdesc->fd_ofiles[fd] = NULL;
34
fdesc->fd_nfiles--;
35
FD_UNLOCK( fdesc );
36
}
37
38
//destroy the given filedescriptor table
39
void
40
fd_destroy( struct filedesc *fdesc ) {
41
KASSERT( fdesc->fd_nfiles == 0 );
42
lock_destroy( fdesc->fd_lk );
43
kfree( fdesc );
44
}
45
46
//create a new filedescriptor tabke
47
int
48
fd_create( struct filedesc **fdesc ) {
49
struct filedesc *fd = NULL;
50
int i = 0;
51
52
fd = kmalloc( sizeof( struct filedesc ) );
53
if( fd == NULL )
54
return ENOMEM;
55
56
//create the lock
57
fd->fd_lk = lock_create( "fd_lk" );
58
if( fd->fd_lk == NULL ) {
59
kfree( fd );
60
return ENOMEM;
61
}
62
63
//initialize all open files
64
for( i = 0; i < MAX_OPEN_FILES; ++i )
65
fd->fd_ofiles[i] = NULL;
66
67
//initially we have no open files.
68
fd->fd_nfiles = 0;
69
70
//we are good to go
71
*fdesc = fd;
72
return 0;
73
}
74
75
/**
76
* attaches a given filehandle inside a specific location
77
* on the filetable.
78
*/
79
int
80
fd_attach_into( struct filedesc *fdesc, struct file *f, int fd ) {
81
FD_LOCK( fdesc );
82
83
//if the file-table already contains something
84
//inside the desired spot, we cannot continue.
85
if( fdesc->fd_ofiles[fd] != NULL ) {
86
FD_UNLOCK( fdesc );
87
return EMFILE;
88
}
89
90
fdesc->fd_ofiles[fd] = f;
91
fdesc->fd_nfiles++;
92
93
FD_UNLOCK( fdesc );
94
return 0;
95
}
96
97
/**
98
* clone a filedescriptor table into another.
99
*/
100
void
101
fd_clone( struct filedesc *source, struct filedesc *fdesc ) {
102
struct file *f = NULL;
103
int i = 0;
104
105
//lock the source file-descriptor table.
106
//and for each file, we copy its pointer into the new table.
107
FD_LOCK( source );
108
for( i = 0; i < MAX_OPEN_FILES; ++i ) {
109
if( source->fd_ofiles[i] != NULL ) {
110
//lock the file for atomicity.
111
//this ensures nobody is writing things out while we are transfering.
112
f = source->fd_ofiles[i];
113
F_LOCK( f );
114
fdesc->fd_ofiles[i] = f;
115
fdesc->fd_nfiles++;
116
117
//at this point we also update the file's
118
//reference count.
119
f->f_refcount++;
120
VOP_INCREF( f->f_vnode );
121
122
//we are done with it.
123
F_UNLOCK( f );
124
}
125
}
126
127
//for sakeness, both file-descriptor tables
128
//must have the same number of open files.
129
KASSERT( source->fd_nfiles == fdesc->fd_nfiles );
130
131
//unlock.
132
FD_UNLOCK( source );
133
}
134
135