AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
fops.c
Go to the documentation of this file.
1
5
6#include <core/system.h>
7#include <fs/vfs.h>
8#include <fs/posix.h>
9#include <fs/pipe.h>
10#include <dev/dev.h>
11#include <net/socket.h>
12#include <aquila/fcntl.h>
13
23{
24 if (!file || !file->vnode || !file->vnode->fs)
25 return -EINVAL;
26
27 /* directories are only read (with readdir) */
28 if (S_ISDIR(file->vnode->mode) && (file->flags & (O_WRONLY | O_RDWR)))
29 return -EISDIR;
30
31 if (ISDEV(file->vnode))
32 return kdev_file_open(&VNODE_DEV(file->vnode), file);
33
34 /* a FIFO's open file becomes an end of its pipe */
35 if (S_ISFIFO(file->vnode->mode))
36 return pipefs_fifo_open(file);
37
38 if (!file->vnode->fs->fops.open)
39 return -ENOSYS;
40
41 return file->vnode->fs->fops.open(file);
42}
43
52ssize_t vfs_file_read(struct file *file, struct iobuf *io)
53{
54 if (file && file->flags & FILE_SOCKET)
55 return socket_recv(file, io, 0, NULL, NULL);
56
57 if (!file || !file->vnode)
58 return -EINVAL;
59
60 /* directories are read with readdir */
61 if (S_ISDIR(file->vnode->mode))
62 return -EISDIR;
63
64 if (ISDEV(file->vnode))
65 return kdev_file_read(&VNODE_DEV(file->vnode), file, io);
66
67 if (!file->vnode->fs)
68 return -EINVAL;
69
70 if (!file->vnode->fs->fops.read)
71 return -ENOSYS;
72
73 return file->vnode->fs->fops.read(file, io);
74}
75
83ssize_t vfs_file_write(struct file *file, struct iobuf *io)
84{
85 if (file && file->flags & FILE_SOCKET)
86 return socket_send(file, io, 0, NULL, 0);
87
88 if (!file || !file->vnode)
89 return -EINVAL;
90
91 if (ISDEV(file->vnode))
92 return kdev_file_write(&VNODE_DEV(file->vnode), file, io);
93
94 if (!file->vnode->fs)
95 return -EINVAL;
96
97 if (!file->vnode->fs->fops.write)
98 return -ENOSYS;
99
100 return file->vnode->fs->fops.write(file, io);
101}
102
111int vfs_file_ioctl(struct file *file, int request, void *argp)
112{
113 if (!file || !file->vnode)
114 return -EINVAL;
115
116 if (ISDEV(file->vnode))
117 return kdev_file_ioctl(&VNODE_DEV(file->vnode), file, request, argp);
118
119 if (!file->vnode->fs)
120 return -EINVAL;
121
122 if (!file->vnode->fs->fops.ioctl)
123 return -ENOSYS;
124
125 return file->vnode->fs->fops.ioctl(file, request, argp);
126}
127
136off_t vfs_file_lseek(struct file *file, off_t offset, int whence)
137{
138 if (!file || !file->vnode)
139 return -EINVAL;
140
141 if (ISDEV(file->vnode))
142 return kdev_file_lseek(&VNODE_DEV(file->vnode), file, offset, whence);
143
144 if (!file->vnode->fs)
145 return -EINVAL;
146
147 /* pipes can't seek */
148 if (!file->vnode->fs->fops.lseek)
149 return -ESPIPE;
150
151 return file->vnode->fs->fops.lseek(file, offset, whence);
152}
153
162ssize_t vfs_file_readdir(struct file *file, struct dirent *dirent)
163{
164 if (!file || !file->vnode || !file->vnode->fs)
165 return -EINVAL;
166
167 if (!S_ISDIR(file->vnode->mode))
168 return -ENOTDIR;
169
170 if (!file->vnode->fs->fops.readdir)
171 return -ENOSYS;
172
173 return file->vnode->fs->fops.readdir(file, dirent);
174}
175
184{
185 if (!file || !file->vnode)
186 return -EINVAL;
187
189
190 if (file->flags & FILE_SOCKET)
191 return socket_shutdown(file, SHUT_RDWR);
192
193 if (ISDEV(file->vnode))
194 return kdev_file_close(&VNODE_DEV(file->vnode), file);
195
196 if (!file->vnode->fs)
197 return -EINVAL;
198
199 /* by default, the vnode's reference is dropped */
200 if (!file->vnode->fs->fops.close)
201 return posix_file_close(file);
202
203 return file->vnode->fs->fops.close(file);
204}
205
213int vfs_file_trunc(struct file *file, off_t len)
214{
215 if (file && file->flags & FILE_SOCKET)
216 return -EINVAL;
217
218 if (!file || !file->vnode)
219 return -EINVAL;
220
221 if (ISDEV(file->vnode))
222 return -EINVAL;
223
224 if (!file->vnode->fs)
225 return -EINVAL;
226
227 if (!file->vnode->fs->fops.trunc)
228 return -ENOSYS;
229
230 return file->vnode->fs->fops.trunc(file, len);
231}
232
243struct waitq *vfs_file_wait_queue(struct file *file, int write)
244{
245 if (file->flags & FILE_SOCKET)
246 return socket_wait_queue(file, write);
247
248 if (!file->vnode)
249 return NULL;
250
251 return write ? file->vnode->write_queue : file->vnode->read_queue;
252}
253
262int vfs_file_can_read(struct file *file, size_t size)
263{
264 if (file && file->flags & FILE_SOCKET)
265 return socket_can_read(file, size);
266
267 if (!file || !file->vnode)
268 return -EINVAL;
269
270 /* reading a regular file or a directory never waits */
271 if (S_ISREG(file->vnode->mode) || S_ISDIR(file->vnode->mode))
272 return 1;
273
274 if (ISDEV(file->vnode))
275 return kdev_file_can_read(&VNODE_DEV(file->vnode), file, size);
276
277 if (!file->vnode->fs)
278 return -EINVAL;
279
280 if (!file->vnode->fs->fops.can_read)
281 return -ENOSYS;
282
283 return file->vnode->fs->fops.can_read(file, size);
284}
285
295int vfs_file_can_write(struct file *file, size_t size)
296{
297 if (file && file->flags & FILE_SOCKET)
298 return socket_can_write(file, size);
299
300 if (!file || !file->vnode)
301 return -EINVAL;
302
303 if (S_ISREG(file->vnode->mode))
304 return 1;
305
306 if (ISDEV(file->vnode))
307 return kdev_file_can_write(&VNODE_DEV(file->vnode), file, size);
308
309 if (!file->vnode->fs)
310 return -EINVAL;
311
312 if (!file->vnode->fs->fops.can_write)
313 return -ENOSYS;
314
315 return file->vnode->fs->fops.can_write(file, size);
316}
317
326{
327 if (!file || !file->vnode)
328 return -EINVAL;
329
330 if (ISDEV(file->vnode))
331 return kdev_file_eof(&VNODE_DEV(file->vnode), file);
332
333 if (!file->vnode->fs)
334 return -EINVAL;
335
336 if (!file->vnode->fs->fops.eof)
337 return -ENOSYS;
338
339 return file->vnode->fs->fops.eof(file);
340}
341
#define VNODE_DEV(vnode)
Definition dev.h:79
void vfs_file_lock_release(struct file *file)
Releases an open file's lock when the file is closed.
Definition flock.c:119
int vfs_file_open(struct file *file)
Opens a file whose vnode is set: a device's driver, a FIFO's pipe, or the filesystem opens it.
Definition fops.c:22
int vfs_file_eof(struct file *file)
Says whether an open file is at its end, so that a read returns 0 rather than waiting.
Definition fops.c:325
struct waitq * vfs_file_wait_queue(struct file *file, int write)
Finds the wait queue that a reader (or a writer) of an open file sleeps on until it can go on,...
Definition fops.c:243
off_t vfs_file_lseek(struct file *file, off_t offset, int whence)
Moves an open file's offset.
Definition fops.c:136
ssize_t vfs_file_readdir(struct file *file, struct dirent *dirent)
Reads the next entry of an open directory.
Definition fops.c:162
int vfs_file_trunc(struct file *file, off_t len)
Changes the length of an open file.
Definition fops.c:213
int vfs_file_can_read(struct file *file, size_t size)
Says whether a read of an open file would go on without waiting, for poll() and select().
Definition fops.c:262
ssize_t vfs_file_close(struct file *file)
Closes an open file, when its last reference goes: its lock is released, then its socket,...
Definition fops.c:183
ssize_t vfs_file_write(struct file *file, struct iobuf *io)
Writes to an open file, at its offset.
Definition fops.c:83
int vfs_file_ioctl(struct file *file, int request, void *argp)
Passes an ioctl() request to an open file's device or filesystem.
Definition fops.c:111
int vfs_file_can_write(struct file *file, size_t size)
Says whether a write to an open file would go on without waiting, for poll(), select() and non-blocki...
Definition fops.c:295
ssize_t vfs_file_read(struct file *file, struct iobuf *io)
Reads from an open file, at its offset.
Definition fops.c:52
ssize_t kdev_file_close(struct devid *dd, struct file *file)
Closes an open device file, through its driver's file operations.
Definition kdev.c:468
off_t kdev_file_lseek(struct devid *dd, struct file *file, off_t offset, int whence)
Moves an open device file's offset, through its driver's file operations.
Definition kdev.c:447
int kdev_file_can_write(struct devid *dd, struct file *file, size_t size)
Asks a device's driver whether a write wouldn't have to wait.
Definition kdev.c:534
int kdev_file_eof(struct devid *dd, struct file *file)
Asks a device's driver whether a read that found no data is at the end of the file.
Definition kdev.c:555
ssize_t kdev_file_write(struct devid *dd, struct file *file, struct iobuf *io)
Writes to an open device file, through its driver's file operations.
Definition kdev.c:423
ssize_t kdev_file_read(struct devid *dd, struct file *file, struct iobuf *io)
Reads an open device file, through its driver's file operations.
Definition kdev.c:402
int kdev_file_ioctl(struct devid *dd, struct file *file, int request, void *argp)
Passes an ioctl() on an open device file to its driver's file operations.
Definition kdev.c:492
int kdev_file_open(struct devid *dd, struct file *file)
Opens a device, through its driver's file operations.
Definition kdev.c:381
int kdev_file_can_read(struct devid *dd, struct file *file, size_t size)
Asks a device's driver whether a read wouldn't have to wait.
Definition kdev.c:513
int pipefs_fifo_open(struct file *file)
Opens a FIFO: the open file's vnode becomes an end of the FIFO's pipe, made by its first open.
Definition pipe.c:239
int posix_file_close(struct file *file)
Closes an open file by dropping its reference to its vnode.
Definition close.c:15
int socket_can_write(struct file *file, size_t len)
Says whether a socket has room to write, for select() and poll().
Definition socket.c:225
#define FILE_SOCKET
Definition socket.h:70
int socket_can_read(struct file *file, size_t len)
Says whether a socket has something to read, for select() and poll().
Definition socket.c:189
struct waitq * socket_wait_queue(struct file *file, int write)
Finds the wait queue that a socket's readers (or writers) sleep on, for select() and poll() to regist...
Definition socket.c:209
int socket_shutdown(struct file *file, int how)
Releases a socket when its open file is closed (its last descriptor went).
Definition socket.c:267
ssize_t socket_recv(struct file *file, struct iobuf *io, int flags, struct sockaddr *from, socklen_t *fromlen)
Receives data from a socket, for recv(), recvfrom() and read().
Definition socket.c:169
ssize_t socket_send(struct file *file, struct iobuf *io, int flags, const struct sockaddr *to, socklen_t tolen)
Sends data on a socket, for send(), sendto() and write().
Definition socket.c:141
#define NULL
Definition stddef.h:27
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
int flags
Definition vfs.h:164
An iobuf.
Definition iobuf.h:35
Definition waitq.h:19
long int ssize_t
Definition types.h:12
long int off_t
Definition types.h:10
#define ISDEV(vnode)
Definition vfs.h:209