1 #include "filesys/fsutil.h"
6 #include "filesys/directory.h"
7 #include "filesys/file.h"
8 #include "filesys/filesys.h"
9 #include "devices/disk.h"
10 #include "threads/malloc.h"
11 #include "threads/palloc.h"
12 #include "threads/vaddr.h"
14 /* List files in the root directory. */
16 fsutil_ls (char **argv UNUSED)
19 char name[NAME_MAX + 1];
21 printf ("Files in the root directory:\n");
22 dir = dir_open_root ();
24 PANIC ("root dir open failed");
25 while (dir_readdir (dir, name))
26 printf ("%s\n", name);
27 printf ("End of listing.\n");
30 /* Prints the contents of file ARGV[1] to the system console as
33 fsutil_cat (char **argv)
35 const char *file_name = argv[1];
40 printf ("Printing '%s' to the console...\n", file_name);
41 file = filesys_open (file_name);
43 PANIC ("%s: open failed", file_name);
44 buffer = palloc_get_page (PAL_ASSERT);
47 off_t pos = file_tell (file);
48 off_t n = file_read (file, buffer, PGSIZE);
52 hex_dump (pos, buffer, n, true);
54 palloc_free_page (buffer);
58 /* Deletes file ARGV[1]. */
60 fsutil_rm (char **argv)
62 const char *file_name = argv[1];
64 printf ("Deleting '%s'...\n", file_name);
65 if (!filesys_remove (file_name))
66 PANIC ("%s: delete failed\n", file_name);
69 /* Copies from the "scratch" disk, hdc or hd1:0 to file ARGV[1]
72 The current sector on the scratch disk must begin with the
73 string "PUT\0" followed by a 32-bit little-endian integer
74 indicating the file size in bytes. Subsequent sectors hold
77 The first call to this function will read starting at the
78 beginning of the scratch disk. Later calls advance across the
79 disk. This disk position is independent of that used for
80 fsutil_get(), so all `put's should precede all `get's. */
82 fsutil_put (char **argv)
84 static disk_sector_t sector = 0;
86 const char *file_name = argv[1];
92 printf ("Putting '%s' into the file system...\n", file_name);
94 /* Allocate buffer. */
95 buffer = malloc (DISK_SECTOR_SIZE);
97 PANIC ("couldn't allocate buffer");
99 /* Open source disk and read file size. */
100 src = disk_get (1, 0);
102 PANIC ("couldn't open source disk (hdc or hd1:0)");
104 /* Read file size. */
105 disk_read (src, sector++, buffer);
106 if (memcmp (buffer, "PUT", 4))
107 PANIC ("%s: missing PUT signature on scratch disk", file_name);
108 size = ((int32_t *) buffer)[1];
110 PANIC ("%s: invalid file size %d", file_name, size);
112 /* Create destination file. */
113 if (!filesys_create (file_name, size))
114 PANIC ("%s: create failed", file_name);
115 dst = filesys_open (file_name);
117 PANIC ("%s: open failed", file_name);
122 int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
123 disk_read (src, sector++, buffer);
124 if (file_write (dst, buffer, chunk_size) != chunk_size)
125 PANIC ("%s: write failed with %"PROTd" bytes unwritten",
135 /* Copies file FILE_NAME from the file system to the scratch disk.
137 The current sector on the scratch disk will receive "GET\0"
138 followed by the file's size in bytes as a 32-bit,
139 little-endian integer. Subsequent sectors receive the file's
142 The first call to this function will write starting at the
143 beginning of the scratch disk. Later calls advance across the
144 disk. This disk position is independent of that used for
145 fsutil_put(), so all `put's should precede all `get's. */
147 fsutil_get (char **argv)
149 static disk_sector_t sector = 0;
151 const char *file_name = argv[1];
157 printf ("Getting '%s' from the file system...\n", file_name);
159 /* Allocate buffer. */
160 buffer = malloc (DISK_SECTOR_SIZE);
162 PANIC ("couldn't allocate buffer");
164 /* Open source file. */
165 src = filesys_open (file_name);
167 PANIC ("%s: open failed", file_name);
168 size = file_length (src);
170 /* Open target disk. */
171 dst = disk_get (1, 0);
173 PANIC ("couldn't open target disk (hdc or hd1:0)");
175 /* Write size to sector 0. */
176 memset (buffer, 0, DISK_SECTOR_SIZE);
177 memcpy (buffer, "GET", 4);
178 ((int32_t *) buffer)[1] = size;
179 disk_write (dst, sector++, buffer);
184 int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
185 if (sector >= disk_size (dst))
186 PANIC ("%s: out of space on scratch disk", file_name);
187 if (file_read (src, buffer, chunk_size) != chunk_size)
188 PANIC ("%s: read failed with %"PROTd" bytes unread", file_name, size);
189 memset (buffer + chunk_size, 0, DISK_SECTOR_SIZE - chunk_size);
190 disk_write (dst, sector++, buffer);