PKUOS - Pintos
Pintos source browser for PKU Operating System course
file.c
Go to the documentation of this file.
1#include "filesys/file.h"
2#include <debug.h>
3#include "filesys/inode.h"
4#include "threads/malloc.h"
5
6/** An open file. */
7struct file
8 {
9 struct inode *inode; /**< File's inode. */
10 off_t pos; /**< Current position. */
11 bool deny_write; /**< Has file_deny_write() been called? */
12 };
13
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. */
17struct file *
19{
20 struct file *file = calloc (1, sizeof *file);
21 if (inode != NULL && file != NULL)
22 {
23 file->inode = inode;
24 file->pos = 0;
25 file->deny_write = false;
26 return file;
27 }
28 else
29 {
31 free (file);
32 return NULL;
33 }
34}
35
36/** Opens and returns a new file for the same inode as FILE.
37 Returns a null pointer if unsuccessful. */
38struct file *
40{
41 return file_open (inode_reopen (file->inode));
42}
43
44/** Closes FILE. */
45void
47{
48 if (file != NULL)
49 {
52 free (file);
53 }
54}
55
56/** Returns the inode encapsulated by FILE. */
57struct inode *
59{
60 return file->inode;
61}
62
63/** Reads SIZE bytes from FILE into BUFFER,
64 starting at the file's current position.
65 Returns the number of bytes actually read,
66 which may be less than SIZE if end of file is reached.
67 Advances FILE's position by the number of bytes read. */
69file_read (struct file *file, void *buffer, off_t size)
70{
71 off_t bytes_read = inode_read_at (file->inode, buffer, size, file->pos);
72 file->pos += bytes_read;
73 return bytes_read;
74}
75
76/** Reads SIZE bytes from FILE into BUFFER,
77 starting at offset FILE_OFS in the file.
78 Returns the number of bytes actually read,
79 which may be less than SIZE if end of file is reached.
80 The file's current position is unaffected. */
82file_read_at (struct file *file, void *buffer, off_t size, off_t file_ofs)
83{
84 return inode_read_at (file->inode, buffer, size, file_ofs);
85}
86
87/** Writes SIZE bytes from BUFFER into FILE,
88 starting at the file's current position.
89 Returns the number of bytes actually written,
90 which may be less than SIZE if end of file is reached.
91 (Normally we'd grow the file in that case, but file growth is
92 not yet implemented.)
93 Advances FILE's position by the number of bytes read. */
95file_write (struct file *file, const void *buffer, off_t size)
96{
97 off_t bytes_written = inode_write_at (file->inode, buffer, size, file->pos);
98 file->pos += bytes_written;
99 return bytes_written;
100}
101
102/** Writes SIZE bytes from BUFFER into FILE,
103 starting at offset FILE_OFS in the file.
104 Returns the number of bytes actually written,
105 which may be less than SIZE if end of file is reached.
106 (Normally we'd grow the file in that case, but file growth is
107 not yet implemented.)
108 The file's current position is unaffected. */
109off_t
110file_write_at (struct file *file, const void *buffer, off_t size,
111 off_t file_ofs)
112{
113 return inode_write_at (file->inode, buffer, size, file_ofs);
114}
115
116/** Prevents write operations on FILE's underlying inode
117 until file_allow_write() is called or FILE is closed. */
118void
120{
121 ASSERT (file != NULL);
122 if (!file->deny_write)
123 {
124 file->deny_write = true;
126 }
127}
128
129/** Re-enables write operations on FILE's underlying inode.
130 (Writes might still be denied by some other file that has the
131 same inode open.) */
132void
134{
135 ASSERT (file != NULL);
136 if (file->deny_write)
137 {
138 file->deny_write = false;
140 }
141}
142
143/** Returns the size of FILE in bytes. */
144off_t
146{
147 ASSERT (file != NULL);
148 return inode_length (file->inode);
149}
150
151/** Sets the current position in FILE to NEW_POS bytes from the
152 start of the file. */
153void
154file_seek (struct file *file, off_t new_pos)
155{
156 ASSERT (file != NULL);
157 ASSERT (new_pos >= 0);
158 file->pos = new_pos;
159}
160
161/** Returns the current position in FILE as a byte offset from the
162 start of the file. */
163off_t
165{
166 ASSERT (file != NULL);
167 return file->pos;
168}
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
Definition: debug.h:31
off_t file_write_at(struct file *file, const void *buffer, off_t size, off_t file_ofs)
Writes SIZE bytes from BUFFER into FILE, starting at offset FILE_OFS in the file.
Definition: file.c:110
void file_seek(struct file *file, off_t new_pos)
Sets the current position in FILE to NEW_POS bytes from the start of the file.
Definition: file.c:154
void file_close(struct file *file)
Closes FILE.
Definition: file.c:46
struct file * file_open(struct inode *inode)
Opens a file for the given INODE, of which it takes ownership, and returns the new file.
Definition: file.c:18
off_t file_write(struct file *file, const void *buffer, off_t size)
Writes SIZE bytes from BUFFER into FILE, starting at the file's current position.
Definition: file.c:95
struct file * file_reopen(struct file *file)
Opens and returns a new file for the same inode as FILE.
Definition: file.c:39
off_t file_length(struct file *file)
Returns the size of FILE in bytes.
Definition: file.c:145
off_t file_read_at(struct file *file, void *buffer, off_t size, off_t file_ofs)
Reads SIZE bytes from FILE into BUFFER, starting at offset FILE_OFS in the file.
Definition: file.c:82
void file_deny_write(struct file *file)
Prevents write operations on FILE's underlying inode until file_allow_write() is called or FILE is cl...
Definition: file.c:119
off_t file_read(struct file *file, void *buffer, off_t size)
Reads SIZE bytes from FILE into BUFFER, starting at the file's current position.
Definition: file.c:69
off_t file_tell(struct file *file)
Returns the current position in FILE as a byte offset from the start of the file.
Definition: file.c:164
struct inode * file_get_inode(struct file *file)
Returns the inode encapsulated by FILE.
Definition: file.c:58
void file_allow_write(struct file *file)
Re-enables write operations on FILE's underlying inode.
Definition: file.c:133
off_t inode_write_at(struct inode *inode, const void *buffer_, off_t size, off_t offset)
Writes SIZE bytes from BUFFER into INODE, starting at OFFSET.
Definition: inode.c:258
off_t inode_read_at(struct inode *inode, void *buffer_, off_t size, off_t offset)
Reads SIZE bytes from INODE into BUFFER, starting at position OFFSET.
Definition: inode.c:201
struct inode * inode_reopen(struct inode *inode)
Reopens and returns INODE.
Definition: inode.c:146
off_t inode_length(const struct inode *inode)
Returns the length, in bytes, of INODE's data.
Definition: inode.c:342
void inode_close(struct inode *inode)
Closes INODE and writes it to disk.
Definition: inode.c:164
void inode_deny_write(struct inode *inode)
Disables writes to INODE.
Definition: inode.c:323
void inode_allow_write(struct inode *inode)
Re-enables writes to INODE.
Definition: inode.c:333
static struct intq buffer
Stores keys from the keyboard and serial port.
Definition: input.c:7
void * calloc(size_t a, size_t b)
Allocates and return A times B bytes initialized to zeroes.
Definition: malloc.c:159
void free(void *p)
Frees block P, which must have been previously allocated with malloc(), calloc(), or realloc().
Definition: malloc.c:219
int32_t off_t
An offset within a file.
Definition: off_t.h:9
#define NULL
Definition: stddef.h:4
An open file.
Definition: file.c:8
struct inode * inode
File's inode.
Definition: file.c:9
bool deny_write
Has file_deny_write() been called?
Definition: file.c:11
off_t pos
Current position.
Definition: file.c:10
In-memory inode.
Definition: inode.c:33