X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilesys%2Ffsutil.c;fp=src%2Ffilesys%2Ffsutil.c;h=8ef5d98f2045f88d3f0a2fb5ed1490476a85a5db;hb=615bf3b3d2a8573ed6fb9ddc0055745e163ac999;hp=81466c2a66dfa008d7d3c1415a9211a392e733c5;hpb=5780c9f434cca090f88463b7f0199d49b4ded288;p=pintos-anon diff --git a/src/filesys/fsutil.c b/src/filesys/fsutil.c index 81466c2..8ef5d98 100644 --- a/src/filesys/fsutil.c +++ b/src/filesys/fsutil.c @@ -1,48 +1,105 @@ #include "filesys/fsutil.h" #include -#include #include #include #include #include "filesys/file.h" #include "filesys/filesys.h" +#include "devices/disk.h" #include "threads/mmu.h" +#include "threads/malloc.h" #include "threads/palloc.h" -/* Destination filename and size for copy-in operations. */ -char *fsutil_copyin_file; -int fsutil_copyin_size; +/* List files in the root directory. */ +void +fsutil_ls (char **argv UNUSED) +{ + printf ("Files in the root directory:\n"); + filesys_list (); + printf ("End of listing.\n"); +} -/* Source filename for copy-out operations. */ -char *fsutil_copyout_file; +/* Prints the contents of file ARGV[1] to the system console as + hex and ASCII. */ +void +fsutil_cat (char **argv) +{ + const char *filename = argv[1]; + + struct file *file; + char *buffer; -/* Name of a file print to print to console. */ -char *fsutil_print_file; + printf ("Printing '%s' to the console...\n", filename); + file = filesys_open (filename); + if (file == NULL) + PANIC ("%s: open failed", filename); + buffer = palloc_get_page (PAL_ASSERT); + for (;;) + { + off_t pos = file_tell (file); + off_t n = file_read (file, buffer, PGSIZE); + if (n == 0) + break; -/* Name of a file to delete. */ -char *fsutil_remove_file; + hex_dump (pos, buffer, n, true); + } + palloc_free_page (buffer); + file_close (file); +} + +/* Deletes file ARGV[1]. */ +void +fsutil_rm (char **argv) +{ + const char *filename = argv[1]; + + printf ("Deleting '%s'...\n", filename); + if (!filesys_remove (filename)) + PANIC ("%s: delete failed\n", filename); +} + +/* Copies from the "scratch" disk, hdc or hd1:0 to file ARGV[1] + in the filesystem. -/* List all files in the filesystem to the system console? */ -bool fsutil_list_files; + The current sector on the scratch disk must begin with the + string "PUT\0" followed by a 32-bit little-endian integer + indicating the file size in bytes. Subsequent sectors hold + the file content. -/* Copies from the "scratch" disk, hdc or hd1:0, - to a file named FILENAME in the filesystem. - The file will be SIZE bytes in length. */ -static void -copy_in (const char *filename, off_t size) + The first call to this function will read starting at the + beginning of the scratch disk. Later calls advance across the + disk. This disk position is independent of that used for + fsutil_get(), so all `put's should precede all `get's. */ +void +fsutil_put (char **argv) { + static disk_sector_t sector = 0; + + const char *filename = argv[1]; struct disk *src; struct file *dst; - disk_sector_t sector; + off_t size; void *buffer; - /* Open source disk. */ + printf ("Putting '%s' into the file system...\n", filename); + + /* Allocate buffer. */ + buffer = malloc (DISK_SECTOR_SIZE); + if (buffer == NULL) + PANIC ("couldn't allocate buffer"); + + /* Open source disk and read file size. */ src = disk_get (1, 0); if (src == NULL) PANIC ("couldn't open source disk (hdc or hd1:0)"); - if (size > (off_t) disk_size (src) * DISK_SECTOR_SIZE) - PANIC ("source disk is too small for %lld-byte file", - (unsigned long long) size); + + /* Read file size. */ + disk_read (src, sector++, buffer); + if (memcmp (buffer, "PUT", 4)) + PANIC ("%s: missing PUT signature on scratch disk", filename); + size = ((int32_t *) buffer)[1]; + if (size < 0) + PANIC ("%s: invalid file size %d", filename, size); /* Create destination file. */ if (!filesys_create (filename, size)) @@ -52,36 +109,49 @@ copy_in (const char *filename, off_t size) PANIC ("%s: open failed", filename); /* Do copy. */ - buffer = palloc_get_page (PAL_ASSERT); - sector = 0; while (size > 0) { int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size; disk_read (src, sector++, buffer); if (file_write (dst, buffer, chunk_size) != chunk_size) - PANIC ("%s: write failed with %lld bytes unwritten", - filename, (unsigned long long) size); + PANIC ("%s: write failed with %"PROTd" bytes unwritten", + filename, size); size -= chunk_size; } - palloc_free_page (buffer); + /* Finish up. */ file_close (dst); + free (buffer); } -/* Copies FILENAME from the file system to the scratch disk. - The first four bytes of the first sector in the disk - receive the file's size in bytes as a little-endian integer. - The second and subsequent sectors receive the file's data. */ -static void -copy_out (const char *filename) +/* Copies file FILENAME from the file system to the scratch disk. + + The current sector on the scratch disk will receive "GET\0" + followed by the file's size in bytes as a 32-bit, + little-endian integer. Subsequent sectors receive the file's + data. + + The first call to this function will write starting at the + beginning of the scratch disk. Later calls advance across the + disk. This disk position is independent of that used for + fsutil_put(), so all `put's should precede all `get's. */ +void +fsutil_get (char **argv) { + static disk_sector_t sector = 0; + + const char *filename = argv[1]; void *buffer; struct file *src; struct disk *dst; off_t size; - disk_sector_t sector; - buffer = palloc_get_page (PAL_ASSERT | PAL_ZERO); + printf ("Getting '%s' from the file system...\n", filename); + + /* Allocate buffer. */ + buffer = malloc (DISK_SECTOR_SIZE); + if (buffer == NULL) + PANIC ("couldn't allocate buffer"); /* Open source file. */ src = filesys_open (filename); @@ -93,76 +163,27 @@ copy_out (const char *filename) dst = disk_get (1, 0); if (dst == NULL) PANIC ("couldn't open target disk (hdc or hd1:0)"); - if (size + DISK_SECTOR_SIZE > (off_t) disk_size (dst) * DISK_SECTOR_SIZE) - PANIC ("target disk is too small for %lld-byte file", - (unsigned long long) size); /* Write size to sector 0. */ - *(uint32_t *) buffer = size; - disk_write (dst, 0, buffer); + memset (buffer, 0, DISK_SECTOR_SIZE); + memcpy (buffer, "GET", 4); + ((int32_t *) buffer)[1] = size; + disk_write (dst, sector++, buffer); /* Do copy. */ - sector = 1; while (size > 0) { int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size; + if (sector >= disk_size (dst)) + PANIC ("%s: out of space on scratch disk", filename); if (file_read (src, buffer, chunk_size) != chunk_size) - PANIC ("%s: read failed with %lld bytes unread", - filename, (unsigned long long) size); + PANIC ("%s: read failed with %"PROTd" bytes unread", filename, size); + memset (buffer + chunk_size, 0, DISK_SECTOR_SIZE - chunk_size); disk_write (dst, sector++, buffer); size -= chunk_size; } - palloc_free_page (buffer); + /* Finish up. */ file_close (src); -} - -/* Executes the filesystem operations described by the variables - declared in fsutil.h. */ -void -fsutil_run (void) -{ - if (fsutil_copyin_file != NULL) - copy_in (fsutil_copyin_file, fsutil_copyin_size); - - if (fsutil_copyout_file != NULL) - copy_out (fsutil_copyout_file); - - if (fsutil_print_file != NULL) - fsutil_print (fsutil_print_file); - - if (fsutil_remove_file != NULL) - { - if (filesys_remove (fsutil_remove_file)) - printf ("%s: removed\n", fsutil_remove_file); - else - PANIC ("%s: remove failed\n", fsutil_remove_file); - } - - if (fsutil_list_files) - filesys_list (); -} - -/* Prints the contents of file FILENAME to the system console as - hex and ASCII. */ -void -fsutil_print (const char *filename) -{ - struct file *file; - char *buffer; - - file = filesys_open (filename); - if (file == NULL) - PANIC ("%s: open failed", filename); - buffer = palloc_get_page (PAL_ASSERT); - for (;;) - { - off_t n = file_read (file, buffer, PGSIZE); - if (n == 0) - break; - - hex_dump (0, buffer, n, true); - } - palloc_free_page (buffer); - file_close (file); + free (buffer); }