1 #include "filesys/file.h"
3 #include "filesys/inode.h"
4 #include "threads/malloc.h"
9 struct inode *inode; /* File's inode. */
10 off_t pos; /* Current position. */
11 bool deny_write; /* Has file_deny_write() been called? */
14 /* Opens a file for the given INODE, of which it takes ownership,
15 and returns the new file. Returns a null pointer if an
16 allocation fails or if INODE is null. */
18 file_open (struct inode *inode)
20 struct file *file = calloc (1, sizeof *file);
21 if (inode != NULL && file != NULL)
25 file->deny_write = false;
36 /* Opens and returns a new file for the same inode as FILE.
37 Returns a null pointer if unsuccessful. */
39 file_reopen (struct file *file)
41 return file_open (inode_reopen (file->inode));
46 file_close (struct file *file)
50 file_allow_write (file);
51 inode_close (file->inode);
56 /* Reads SIZE bytes from FILE into BUFFER,
57 starting at the file's current position.
58 Returns the number of bytes actually read,
59 which may be less than SIZE if end of file is reached.
60 Advances FILE's position by the number of bytes read. */
62 file_read (struct file *file, void *buffer, off_t size)
64 off_t bytes_read = inode_read_at (file->inode, buffer, size, file->pos);
65 file->pos += bytes_read;
69 /* Reads SIZE bytes from FILE into BUFFER,
70 starting at offset FILE_OFS in the file.
71 Returns the number of bytes actually read,
72 which may be less than SIZE if end of file is reached.
73 The file's current position is unaffected. */
75 file_read_at (struct file *file, void *buffer, off_t size, off_t file_ofs)
77 return inode_read_at (file->inode, buffer, size, file_ofs);
80 /* Writes SIZE bytes from BUFFER into FILE,
81 starting at the file's current position.
82 Returns the number of bytes actually written,
83 which may be less than SIZE if end of file is reached.
84 (Normally we'd grow the file in that case, but file growth is
86 Advances FILE's position by the number of bytes read. */
88 file_write (struct file *file, const void *buffer, off_t size)
90 off_t bytes_written = inode_write_at (file->inode, buffer, size, file->pos);
91 file->pos += bytes_written;
95 /* Writes SIZE bytes from BUFFER into FILE,
96 starting at offset FILE_OFS in the file.
97 Returns the number of bytes actually written,
98 which may be less than SIZE if end of file is reached.
99 (Normally we'd grow the file in that case, but file growth is
100 not yet implemented.)
101 The file's current position is unaffected. */
103 file_write_at (struct file *file, const void *buffer, off_t size,
106 return inode_write_at (file->inode, buffer, size, file_ofs);
109 /* Prevents write operations on FILE's underlying inode
110 until file_allow_write() is called or FILE is closed. */
112 file_deny_write (struct file *file)
114 ASSERT (file != NULL);
115 if (!file->deny_write)
117 file->deny_write = true;
118 inode_deny_write (file->inode);
122 /* Re-enables write operations on FILE's underlying inode.
123 (Writes might still be denied by some other file that has the
126 file_allow_write (struct file *file)
128 ASSERT (file != NULL);
129 if (file->deny_write)
131 file->deny_write = false;
132 inode_allow_write (file->inode);
136 /* Returns the size of FILE in bytes. */
138 file_length (struct file *file)
140 ASSERT (file != NULL);
141 return inode_length (file->inode);
144 /* Sets the current position in FILE to NEW_POS bytes from the
145 start of the file. */
147 file_seek (struct file *file, off_t new_pos)
149 ASSERT (file != NULL);
150 ASSERT (new_pos >= 0);
154 /* Returns the current position in FILE as a byte offset from the
155 start of the file. */
157 file_tell (struct file *file)
159 ASSERT (file != NULL);