PatchworkOS  966e257
A non-POSIX operating system.
Loading...
Searching...
No Matches
file_table.c
Go to the documentation of this file.
2
4
5#include <sys/bitmap.h>
6
8{
9 for (uint64_t i = 0; i < CONFIG_MAX_FD; i++)
10 {
11 table->files[i] = NULL;
12 }
13 BITMAP_DEFINE_INIT(table->bitmap, CONFIG_MAX_FD);
14 lock_init(&table->lock);
15}
16
18{
19 LOCK_SCOPE(&table->lock);
20
21 for (uint64_t i = 0; i < CONFIG_MAX_FD; i++)
22 {
23 if (table->files[i] != NULL)
24 {
25 UNREF(table->files[i]);
26 table->files[i] = NULL;
27 }
28 }
29}
30
32{
33 if (table == NULL)
34 {
35 errno = EINVAL;
36 return NULL;
37 }
38
39 LOCK_SCOPE(&table->lock);
40
41 if (fd >= CONFIG_MAX_FD || table->files[fd] == NULL)
42 {
43 errno = EBADF;
44 return NULL;
45 }
46
47 return REF(table->files[fd]);
48}
49
51{
52 if (table == NULL || file == NULL)
53 {
54 errno = EINVAL;
55 return ERR;
56 }
57
58 LOCK_SCOPE(&table->lock);
59
60 uint64_t index = bitmap_find_first_clear(&table->bitmap, 0, CONFIG_MAX_FD);
61 if (index >= CONFIG_MAX_FD)
62 {
63 errno = EMFILE;
64 return ERR;
65 }
66
67 table->files[index] = REF(file);
68 bitmap_set(&table->bitmap, index);
69 return (fd_t)index;
70}
71
73{
74 if (table == NULL)
75 {
76 errno = EINVAL;
77 return ERR;
78 }
79
80 LOCK_SCOPE(&table->lock);
81
82 if (fd >= CONFIG_MAX_FD || table->files[fd] == NULL)
83 {
84 errno = EBADF;
85 return ERR;
86 }
87
88 UNREF(table->files[fd]);
89 table->files[fd] = NULL;
90 bitmap_clear(&table->bitmap, fd);
91 return 0;
92}
93
95{
96 if (table == NULL)
97 {
98 errno = EINVAL;
99 return ERR;
100 }
101
102 LOCK_SCOPE(&table->lock);
103
104 for (fd_t fd = min; fd < max && fd < CONFIG_MAX_FD; fd++)
105 {
106 if (table->files[fd] != NULL)
107 {
108 UNREF(table->files[fd]);
109 table->files[fd] = NULL;
110 bitmap_clear(&table->bitmap, fd);
111 }
112 }
113
114 return 0;
115}
116
118{
119 if (table == NULL || file == NULL)
120 {
121 errno = EINVAL;
122 return ERR;
123 }
124
125 LOCK_SCOPE(&table->lock);
126
127 if (fd >= CONFIG_MAX_FD)
128 {
129 errno = EBADF;
130 return ERR;
131 }
132
133 if (table->files[fd] != NULL)
134 {
135 UNREF(table->files[fd]);
136 table->files[fd] = NULL;
137 }
138
139 table->files[fd] = REF(file);
140 bitmap_set(&table->bitmap, fd);
141 return fd;
142}
143
145{
146 if (table == NULL)
147 {
148 errno = EINVAL;
149 return ERR;
150 }
151
152 LOCK_SCOPE(&table->lock);
153
154 if (oldFd >= CONFIG_MAX_FD || table->files[oldFd] == NULL)
155 {
156 errno = EBADF;
157 return ERR;
158 }
159
160 uint64_t index = bitmap_find_first_clear(&table->bitmap, 0, CONFIG_MAX_FD);
161 if (index >= CONFIG_MAX_FD)
162 {
163 errno = EMFILE;
164 return ERR;
165 }
166
167 table->files[index] = REF(table->files[oldFd]);
168 bitmap_set(&table->bitmap, index);
169 return (fd_t)index;
170}
171
173{
174 if (table == NULL)
175 {
176 errno = EINVAL;
177 return ERR;
178 }
179
180 if (oldFd == newFd)
181 {
182 return newFd;
183 }
184
185 LOCK_SCOPE(&table->lock);
186
187 if (oldFd >= CONFIG_MAX_FD || newFd >= CONFIG_MAX_FD || table->files[oldFd] == NULL)
188 {
189 errno = EBADF;
190 return ERR;
191 }
192
193 if (table->files[newFd] != NULL)
194 {
195 UNREF(table->files[newFd]);
196 table->files[newFd] = NULL;
197 }
198
199 table->files[newFd] = REF(table->files[oldFd]);
200 bitmap_set(&table->bitmap, newFd);
201 return newFd;
202}
203
205{
206 if (dest == NULL || src == NULL)
207 {
208 errno = EINVAL;
209 return ERR;
210 }
211
212 LOCK_SCOPE(&src->lock);
213 LOCK_SCOPE(&dest->lock);
214
215 for (fd_t i = min; i < max && i < CONFIG_MAX_FD; i++)
216 {
217 if (src->files[i] == NULL)
218 {
219 continue;
220 }
221
222 if (dest->files[i] != NULL)
223 {
224 UNREF(dest->files[i]);
225 dest->files[i] = NULL;
226 }
227
228 dest->files[i] = REF(src->files[i]);
229 bitmap_set(&dest->bitmap, i);
230 }
231
232 return 0;
233}
234
236{
237 if (table == NULL)
238 {
239 return;
240 }
241
242 LOCK_SCOPE(&table->lock);
243
244 for (uint64_t i = 0; i < CONFIG_MAX_FD; i++)
245 {
246 if (table->files[i] != NULL)
247 {
248 UNREF(table->files[i]);
249 table->files[i] = NULL;
250 bitmap_clear(&table->bitmap, i);
251 }
252 }
253}
254
256{
257 return file_table_free(&sched_process()->fileTable, fd);
258}
259
261{
262 return file_table_dup(&sched_process()->fileTable, oldFd);
263}
264
266{
267 return file_table_dup2(&sched_process()->fileTable, oldFd, newFd);
268}
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
Definition syscall.h:163
@ SYS_CLOSE
Definition syscall.h:76
@ SYS_DUP
Definition syscall.h:90
@ SYS_DUP2
Definition syscall.h:91
fd_t file_table_dup2(file_table_t *table, fd_t oldFd, fd_t newFd)
Duplicate a file descriptor to a specific file descriptor.
Definition file_table.c:172
uint64_t file_table_free(file_table_t *table, fd_t fd)
Free a file descriptor.
Definition file_table.c:72
file_t * file_table_get(file_table_t *table, fd_t fd)
Get a file from its file descriptor.
Definition file_table.c:31
fd_t file_table_alloc(file_table_t *table, file_t *file)
Allocate a new file descriptor for a file.
Definition file_table.c:50
uint64_t file_table_copy(file_table_t *dest, file_table_t *src, fd_t min, fd_t max)
Copy a file table, closing any overlapping file descriptors.
Definition file_table.c:204
void file_table_close_all(file_table_t *table)
Close all files in the file table.
Definition file_table.c:235
void file_table_init(file_table_t *table)
Initialize a file table.
Definition file_table.c:7
fd_t file_table_set(file_table_t *table, fd_t fd, file_t *file)
Set a specific file descriptor to a file.
Definition file_table.c:117
void file_table_deinit(file_table_t *table)
Deinitialize a file table.
Definition file_table.c:17
uint64_t file_table_free_range(file_table_t *table, fd_t min, fd_t max)
Free a range of file descriptors.
Definition file_table.c:94
fd_t file_table_dup(file_table_t *table, fd_t oldFd)
Duplicate a file descriptor.
Definition file_table.c:144
process_t * sched_process(void)
Retrieves the process of the currently running thread.
Definition sched.c:620
static void lock_init(lock_t *lock)
Initializes a lock.
Definition lock.h:86
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
Definition lock.h:57
#define REF(ptr)
Increment reference count.
Definition ref.h:65
#define UNREF(ptr)
Decrement reference count.
Definition ref.h:80
#define CONFIG_MAX_FD
Maximum file descriptor configuration.
Definition config.h:47
#define EINVAL
Invalid argument.
Definition errno.h:142
#define EMFILE
Too many open files.
Definition errno.h:152
#define errno
Error number variable.
Definition errno.h:27
#define EBADF
Bad file number.
Definition errno.h:77
void bitmap_clear(bitmap_t *map, uint64_t index)
Clear a bit in the bitmap.
Definition bitmap_clear.c:3
void bitmap_set(bitmap_t *map, uint64_t index)
Set a bit in the bitmap.
Definition bitmap_set.c:3
uint64_t bitmap_find_first_clear(bitmap_t *map, uint64_t startIdx, uint64_t endIdx)
Find the first clear bit in the bitmap.
#define BITMAP_DEFINE_INIT(name, bits)
Initialize a bitmap defined with BITMAP_DEFINE.
Definition bitmap.h:107
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ fd_t
A file descriptor.
Definition fd_t.h:12
static dentry_t * file
Definition log_file.c:22
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
File structure.
Definition file.h:39
File table structure.
Definition file_table.h:24
file_t * files[CONFIG_MAX_FD]
Definition file_table.h:25
lock_t lock
Definition file_table.h:27