e6f282f8062dc2c383f3a540c08b73d0a9628ce7
[pintos-anon] / src / filesys / file.c
1 #include "file.h"
2
3 #ifdef FILESYS_STUB
4 #include "debug.h"
5 #include "filesys-stub.h"
6 #include "lib.h"
7 #include "malloc.h"
8
9 bool
10 file_open (struct file *file, const char *name) 
11 {
12   struct dir dir;
13   disk_sector_no hdr_sector;
14   bool success = false;
15
16   dir_init (&dir, NUM_DIR_ENTRIES);
17   dir_read (&dir, &root_dir_file);
18   if (dir_lookup (&dir, name, &hdr_sector))
19     success = file_open_sector (file, hdr_sector);
20
21   dir_destroy (&dir);
22   return success;
23 }
24
25 bool
26 file_open_sector (struct file *file, disk_sector_no hdr_sector) 
27 {
28   file->pos = 0;
29   return filehdr_read (&file->hdr, hdr_sector);
30 }
31
32 void
33 file_close (struct file *file) 
34 {
35   filehdr_destroy (file);
36 }
37
38 off_t
39 file_read (struct file *file, void *buffer, off_t size) 
40 {
41   off_t retval = file_read_at (file, buffer, size, file->pos);
42   file->pos += retval;
43   return retval;
44 }
45
46 off_t
47 file_read_at (struct file *file, void *buffer_, off_t size, off_t start) 
48 {
49   uint8_t *buffer = buffer_;
50   off_t bytes_read = 0;
51   uint8_t *bounce;
52
53   bounce = malloc (DISK_SECTOR_SIZE);
54   while (size > 0) 
55     {
56       /* Disk sector to read, starting byte offset within sector. */
57       off_t sector_idx = filehdr_byte_to_sector (file->hdr);
58       int sector_ofs = start % DISK_SECTOR_SIZE;
59
60       /* Bytes left in file, bytes left in sector. */
61       off_t file_left = filehdr_size (file->hdr) - start;
62       off_t sector_left = DISK_SECTOR_SIZE - sector_ofs;
63
64       /* Number of bytes to actually copy out of this sector. */
65       int chunk_size = file_left < sector_left ? file_left : sector_left;
66       if (chunk_size == 0)
67         break;
68
69       /* Read sector into bounce buffer, then copy into caller's
70          buffer. */
71       disk_read (disk, sector_idx, bounce);
72       memcpy (buffer + bytes_read, bounce + sector_ofs, chunk_size);
73
74       /* Advance. */
75       size -= chunk_size;
76       start += chunk_size;
77       bytes_read += chunk_size;
78     }
79   free (bounce);
80
81   return bytes_read;
82 }
83
84 off_t
85 file_write (struct file *file, const void *buffer, off_t size) 
86 {
87   off_t retval = file_write_at (file, buffer, size, file->pos);
88   file->pos += retval;
89   return retval;
90 }
91
92 off_t
93 file_write_at (struct file *file, const void *buffer_, off_t size,
94                off_t start) 
95 {
96   uint8_t *buffer = buffer_;
97   off_t bytes_read = 0;
98   uint8_t *bounce;
99
100   bounce = malloc (DISK_SECTOR_SIZE);
101   while (size > 0) 
102     {
103       /* Disk sector to read, starting byte offset within sector. */
104       off_t sector_idx = filehdr_byte_to_sector (file->hdr);
105       int sector_ofs = start % DISK_SECTOR_SIZE;
106
107       /* Bytes left in file, bytes left in sector. */
108       off_t file_left = filehdr_size (file->hdr) - start;
109       off_t sector_left = DISK_SECTOR_SIZE - sector_ofs;
110
111       /* Number of bytes to actually copy out of this sector. */
112       int chunk_size = file_left < sector_left ? file_left : sector_left;
113       if (chunk_size == 0)
114         break;
115
116       /* Read sector into bounce buffer, then copy into caller's
117          buffer. */
118       disk_read (disk, sector_idx, bounce);
119       memcpy (buffer + bytes_read, bounce + sector_ofs, chunk_size);
120
121       /* Advance. */
122       size -= chunk_size;
123       start += chunk_size;
124       bytes_read += chunk_size;
125     }
126   free (bounce);
127
128   return bytes_read;
129 }
130
131 off_t
132 file_length (struct file *file) 
133 {
134   int32_t length;
135
136   filesys_stub_lock ();
137   filesys_stub_put_string ("length");
138   filesys_stub_put_file (file);
139   filesys_stub_match_string ("length");
140   length = filesys_stub_get_int32 ();
141   filesys_stub_unlock ();
142
143   return length;
144 }
145
146 void
147 file_seek (struct file *file, off_t pos) 
148 {
149   filesys_stub_lock ();
150   filesys_stub_put_string ("seek");
151   filesys_stub_put_file (file);
152   filesys_stub_put_uint32 (pos);
153   filesys_stub_match_string ("seek");
154   filesys_stub_unlock ();
155 }
156
157 off_t
158 file_tell (struct file *file) 
159 {
160   int32_t pos;
161
162   filesys_stub_lock ();
163   filesys_stub_put_string ("tell");
164   filesys_stub_put_file (file);
165   filesys_stub_match_string ("tell");
166   pos = filesys_stub_get_int32 ();
167   filesys_stub_unlock ();
168
169   return pos;
170 }
171 #endif /* FILESYS_STUB */