X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=solutions%2Fp4.patch;h=61ef9e8ab541aae4cd490003585a50b318db4c91;hb=977edaf97eb505eb0f752e2357817539b20d90b5;hp=2342ca94417654e643b7e5b3fcdd5148647319d1;hpb=eeb91a07868f8260736fc553bf2e30c8a81c4fbf;p=pintos-anon diff --git a/solutions/p4.patch b/solutions/p4.patch index 2342ca9..61ef9e8 100644 --- a/solutions/p4.patch +++ b/solutions/p4.patch @@ -6,7 +6,7 @@ diff -u src/Makefile.build~ src/Makefile.build userprog_SRC += userprog/tss.c # TSS management. # No virtual memory code yet. --#vm_SRC = vm/filename.c # Some file. +-#vm_SRC = vm/file.c # Some file. +vm_SRC = vm/page.c +vm_SRC += vm/frame.c +vm_SRC += vm/swap.c @@ -722,25 +722,32 @@ diff -u src/filesys/directory.c~ src/filesys/directory.c return success; } -@@ -205,8 +210,10 @@ dir_list (const struct dir *dir) +@@ -216,14 +216,17 @@ + { struct dir_entry e; - size_t ofs; - + + inode_lock (dir->inode); - for (ofs = 0; inode_read_at (dir->inode, &e, sizeof e, ofs) == sizeof e; - ofs += sizeof e) - if (e.in_use) - printf ("%s\n", e.name); + while (inode_read_at (dir->inode, &e, sizeof e, dir->pos) == sizeof e) + { + dir->pos += sizeof e; + if (e.in_use) + { + strlcpy (name, e.name, NAME_MAX + 1); ++ inode_unlock (dir->inode); + return true; + } + } + inode_unlock (dir->inode); + return false; } Index: src/filesys/directory.h diff -u src/filesys/directory.h~ src/filesys/directory.h --- src/filesys/directory.h 2006-05-18 22:26:02.000000000 -0700 +++ src/filesys/directory.h 2006-05-18 22:05:40.000000000 -0700 @@ -12,6 +11,5 @@ - #define NAME_MAX 14 - struct inode; + + /* Opening and closing directories. */ -bool dir_create (disk_sector_t sector, size_t entry_cnt); struct dir *dir_open (struct inode *); struct dir *dir_open_root (void); @@ -773,10 +780,10 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c #include "devices/disk.h" +#include "threads/thread.h" - /* The disk that contains the filesystem. */ + /* The disk that contains the file system. */ struct disk *filesys_disk; @@ -23,6 +25,7 @@ filesys_init (bool format) - PANIC ("hd0:1 (hdb) not present, filesystem initialization failed"); + PANIC ("hd0:1 (hdb) not present, file system initialization failed"); inode_init (); + cache_init (); @@ -828,10 +835,10 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c +/* Resolves relative or absolute file NAME. + Returns true if successful, false on failure. + Stores the directory corresponding to the name into *DIRP, -+ and the file name part into BASENAME. */ ++ and the file name part into BASE_NAME. */ +static bool +resolve_name (const char *name, -+ struct dir **dirp, char basename[NAME_MAX + 1]) ++ struct dir **dirp, char base_name[NAME_MAX + 1]) +{ + struct dir *dir = NULL; + struct inode *inode; @@ -871,14 +878,14 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c + + /* Return our results. */ + *dirp = dir; -+ strlcpy (basename, part, NAME_MAX + 1); ++ strlcpy (base_name, part, NAME_MAX + 1); + return true; + + error: + /* Return failure. */ + dir_close (dir); + *dirp = NULL; -+ basename[0] = '\0'; ++ base_name[0] = '\0'; + return false; } @@ -891,24 +898,24 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c +filesys_create (const char *name, off_t initial_size, enum inode_type type) { + struct dir *dir; -+ char basename[NAME_MAX + 1]; ++ char base_name[NAME_MAX + 1]; disk_sector_t inode_sector = 0; - struct dir *dir = dir_open_root (); - bool success = (dir != NULL - && free_map_allocate (1, &inode_sector) - && inode_create (inode_sector, initial_size) - && dir_add (dir, name, inode_sector)); -+ bool success = (resolve_name (name, &dir, basename) ++ bool success = (resolve_name (name, &dir, base_name) + && free_map_allocate (&inode_sector) + && inode_create (inode_sector, initial_size, type) -+ && dir_add (dir, basename, inode_sector)); ++ && dir_add (dir, base_name, inode_sector)); if (!success && inode_sector != 0) - free_map_release (inode_sector, 1); + free_map_release (inode_sector); dir_close (dir); return success; -@@ -64,17 +161,18 @@ filesys_create (const char *name, off_t +@@ -64,17 +161,22 @@ filesys_create (const char *name, off_t otherwise. Fails if no file named NAME exists, or if an internal memory allocation fails. */ @@ -917,14 +924,18 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c filesys_open (const char *name) { - struct dir *dir = dir_open_root (); -+ struct dir *dir; -+ char basename[NAME_MAX + 1]; ++ struct dir *dir = NULL; ++ char base_name[NAME_MAX + 1]; struct inode *inode = NULL; - if (dir != NULL) - dir_lookup (dir, name, &inode); -+ if (resolve_name (name, &dir, basename)) -+ dir_lookup (dir, basename, &inode); ++ if (!strcmp (name, "/")) ++ inode = inode_open (ROOT_DIR_SECTOR); ++ else if (!strcmp (name, ".")) ++ inode = inode_reopen (dir_get_inode (thread_current ()->wd)); ++ else if (resolve_name (name, &dir, base_name)) ++ dir_lookup (dir, base_name, &inode); dir_close (dir); - return file_open (inode); @@ -932,23 +943,23 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c } /* Deletes the file named NAME. -@@ -84,13 +182,56 @@ filesys_open (const char *name) +@@ -84,7 +182,11 @@ filesys_open (const char *name) bool filesys_remove (const char *name) { - struct dir *dir = dir_open_root (); - bool success = dir != NULL && dir_remove (dir, name); + struct dir *dir = NULL; -+ char basename[NAME_MAX + 1]; ++ char base_name[NAME_MAX + 1]; + bool success = false; + -+ if (resolve_name (name, &dir, basename)) -+ success = dir_remove (dir, basename); ++ if (resolve_name (name, &dir, base_name)) ++ success = dir_remove (dir, base_name); dir_close (dir); +@@ -91,5 +193,44 @@ return success; } - +/* Change current directory to NAME. + Return true if successful, false on failure. */ +bool @@ -967,11 +978,11 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c + } + else + { -+ char basename[NAME_MAX + 1]; ++ char base_name[NAME_MAX + 1]; + struct inode *base_inode; + struct dir *base_dir; -+ if (!resolve_name (name, &dir, basename) -+ || !dir_lookup (dir, basename, &base_inode) ++ if (!resolve_name (name, &dir, base_name) ++ || !dir_lookup (dir, base_name, &base_inode) + || (base_dir = dir_open (base_inode)) == NULL) + { + dir_close (dir); @@ -988,28 +999,9 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c + return true; +} + - /* Prints a list of files in the filesystem to the system - console. - Returns true if successful, false on failure, -@@ -98,15 +239,9 @@ filesys_remove (const char *name) - bool - filesys_list (void) - { -- struct dir *dir = dir_open_root (); -- if (dir != NULL) -- { -- dir_list (dir); -- dir_close (dir); -- return true; -- } -- else -- return false; -+ dir_list (thread_current ()->wd); -+ -+ return true; - } static void must_succeed_function (int, bool) NO_INLINE; + #define MUST_SUCCEED(EXPR) must_succeed_function (__LINE__, EXPR) @@ -129,8 +264,8 @@ filesys_self_test (void) { /* Create file and check that it contains zeros @@ -1042,7 +1034,7 @@ diff -u src/filesys/filesys.c~ src/filesys/filesys.c @@ -173,9 +308,13 @@ static void do_format (void) { - printf ("Formatting filesystem..."); + printf ("Formatting file system..."); + + /* Set up free map. */ free_map_create (); @@ -1067,7 +1059,7 @@ diff -u src/filesys/filesys.h~ src/filesys/filesys.h /* Sectors of system file inodes. */ #define FREE_MAP_SECTOR 0 /* Free map file inode sector. */ -@@ -13,8 +14,8 @@ extern struct disk *filesys_disk; +@@ -13,9 +14,10 @@ extern struct disk *filesys_disk; void filesys_init (bool format); void filesys_done (void); @@ -1076,8 +1068,10 @@ diff -u src/filesys/filesys.h~ src/filesys/filesys.h +bool filesys_create (const char *name, off_t initial_size, enum inode_type); +struct inode *filesys_open (const char *name); bool filesys_remove (const char *name); - bool filesys_chdir (const char *name); - bool filesys_list (void); ++bool filesys_chdir (const char *name); + + void filesys_self_test (void); + Index: src/filesys/free-map.c diff -u src/filesys/free-map.c~ src/filesys/free-map.c --- src/filesys/free-map.c 2005-06-18 20:20:48.000000000 -0700 @@ -1198,32 +1192,32 @@ diff -u src/filesys/fsutil.c~ src/filesys/fsutil.c @@ -30,7 +30,7 @@ fsutil_cat (char **argv) char *buffer; - printf ("Printing '%s' to the console...\n", filename); -- file = filesys_open (filename); -+ file = file_open (filesys_open (filename)); + printf ("Printing '%s' to the console...\n", file_name); +- file = filesys_open (file_name); ++ file = file_open (filesys_open (file_name)); if (file == NULL) - PANIC ("%s: open failed", filename); + PANIC ("%s: open failed", file_name); buffer = palloc_get_page (PAL_ASSERT); @@ -102,9 +102,9 @@ fsutil_put (char **argv) - PANIC ("%s: invalid file size %d", filename, size); + PANIC ("%s: invalid file size %d", file_name, size); /* Create destination file. */ -- if (!filesys_create (filename, size)) -+ if (!filesys_create (filename, size, FILE_INODE)) - PANIC ("%s: create failed", filename); -- dst = filesys_open (filename); -+ dst = file_open (filesys_open (filename)); +- if (!filesys_create (file_name, size)) ++ if (!filesys_create (file_name, size, FILE_INODE)) + PANIC ("%s: create failed", file_name); +- dst = filesys_open (file_name); ++ dst = file_open (filesys_open (file_name)); if (dst == NULL) - PANIC ("%s: open failed", filename); + PANIC ("%s: open failed", file_name); @@ -154,7 +154,7 @@ fsutil_get (char **argv) PANIC ("couldn't allocate buffer"); /* Open source file. */ -- src = filesys_open (filename); -+ src = file_open (filesys_open (filename)); +- src = filesys_open (file_name); ++ src = file_open (filesys_open (file_name)); if (src == NULL) - PANIC ("%s: open failed", filename); + PANIC ("%s: open failed", file_name); size = file_length (src); Index: src/filesys/inode.c diff -u src/filesys/inode.c~ src/filesys/inode.c @@ -2206,7 +2200,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c + thread. */ +struct exec_info + { -+ const char *filename; /* Program to load. */ ++ const char *file_name; /* Program to load. */ + struct semaphore load_done; /* "Up"ed when loading complete. */ + struct wait_status *wait_status; /* Child process. */ + struct dir *wd; /* Working directory. */ @@ -2214,10 +2208,10 @@ diff -u src/userprog/process.c~ src/userprog/process.c + }; /* Starts a new thread running a user program loaded from - FILENAME. The new thread may be scheduled (and may even exit) + FILE_NAME. The new thread may be scheduled (and may even exit) @@ -28,41 +43,78 @@ static bool load (const char *cmdline, v tid_t - process_execute (const char *filename) + process_execute (const char *file_name) { - char *fn_copy; + struct dir *wd = thread_current ()->wd; @@ -2226,23 +2220,23 @@ diff -u src/userprog/process.c~ src/userprog/process.c + char *save_ptr; tid_t tid; -- /* Make a copy of FILENAME. +- /* Make a copy of FILE_NAME. - Otherwise there's a race between the caller and load(). */ - fn_copy = palloc_get_page (0); - if (fn_copy == NULL) + /* Initialize exec_info. */ -+ exec.filename = filename; ++ exec.file_name = file_name; + exec.wd = wd != NULL ? dir_reopen (wd) : dir_open_root (); + if (exec.wd == NULL) return TID_ERROR; -- strlcpy (fn_copy, filename, PGSIZE); +- strlcpy (fn_copy, file_name, PGSIZE); + sema_init (&exec.load_done, 0); - /* Create a new thread to execute FILENAME. */ -- tid = thread_create (filename, PRI_DEFAULT, execute_thread, fn_copy); + /* Create a new thread to execute FILE_NAME. */ +- tid = thread_create (file_name, PRI_DEFAULT, execute_thread, fn_copy); - if (tid == TID_ERROR) - palloc_free_page (fn_copy); -+ strlcpy (thread_name, filename, sizeof thread_name); ++ strlcpy (thread_name, file_name, sizeof thread_name); + strtok_r (thread_name, " ", &save_ptr); + tid = thread_create (thread_name, PRI_DEFAULT, execute_thread, &exec); + if (tid != TID_ERROR) @@ -2265,10 +2259,10 @@ diff -u src/userprog/process.c~ src/userprog/process.c /* A thread function that loads a user process and starts it running. */ static void --execute_thread (void *filename_) +-execute_thread (void *file_name_) +execute_thread (void *exec_) { -- char *filename = filename_; +- char *file_name = file_name_; + struct exec_info *exec = exec_; struct intr_frame if_; bool success; @@ -2280,11 +2274,11 @@ diff -u src/userprog/process.c~ src/userprog/process.c if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG; if_.cs = SEL_UCSEG; if_.eflags = FLAG_IF | FLAG_MBS; -- success = load (filename, &if_.eip, &if_.esp); -+ success = load (exec->filename, &if_.eip, &if_.esp); +- success = load (file_name, &if_.eip, &if_.esp); ++ success = load (exec->file_name, &if_.eip, &if_.esp); - /* If load failed, quit. */ -- palloc_free_page (filename); +- palloc_free_page (file_name); + /* Allocate wait_status. */ + if (success) + { @@ -2308,7 +2302,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c if (!success) thread_exit (); -@@ -76,18 +128,47 @@ execute_thread (void *filename_) +@@ -76,18 +128,47 @@ execute_thread (void *file_name_) NOT_REACHED (); } @@ -2410,11 +2404,11 @@ diff -u src/userprog/process.c~ src/userprog/process.c and its initial stack pointer into *ESP. Returns true if successful, false otherwise. */ bool --load (const char *filename, void (**eip) (void), void **esp) +-load (const char *file_name, void (**eip) (void), void **esp) +load (const char *cmd_line, void (**eip) (void), void **esp) { struct thread *t = thread_current (); -+ char filename[NAME_MAX + 2]; ++ char file_name[NAME_MAX + 2]; struct Elf32_Ehdr ehdr; struct file *file = NULL; off_t file_ofs; @@ -2423,7 +2417,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c int i; /* Allocate and activate page directory. */ -@@ -220,13 +330,28 @@ load (const char *filename, void (**eip) +@@ -220,13 +330,28 @@ load (const char *file_name, void (**eip) goto done; process_activate (); @@ -2433,27 +2427,27 @@ diff -u src/userprog/process.c~ src/userprog/process.c + goto done; + hash_init (t->pages, page_hash, page_less, NULL); + -+ /* Extract filename from command line. */ ++ /* Extract file_name from command line. */ + while (*cmd_line == ' ') + cmd_line++; -+ strlcpy (filename, cmd_line, sizeof filename); -+ cp = strchr (filename, ' '); ++ strlcpy (file_name, cmd_line, sizeof file_name); ++ cp = strchr (file_name, ' '); + if (cp != NULL) + *cp = '\0'; + /* Open executable file. */ -- file = filesys_open (filename); -+ t->bin_file = file = file_open (filesys_open (filename)); +- file = filesys_open (file_name); ++ t->bin_file = file = file_open (filesys_open (file_name)); if (file == NULL) { - printf ("load: %s: open failed\n", filename); + printf ("load: %s: open failed\n", file_name); goto done; } + file_deny_write (file); /* Read and verify executable header. */ if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr -@@ -301,7 +426,7 @@ load (const char *filename, void (**eip) +@@ -301,7 +426,7 @@ load (const char *file_name, void (**eip) } /* Set up stack. */ @@ -2462,7 +2456,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c goto done; /* Start address. */ -@@ -311,14 +436,11 @@ load (const char *filename, void (**eip) +@@ -311,14 +436,11 @@ load (const char *file_name, void (**eip) done: /* We arrive here whether the load is successful or not. */ @@ -2661,7 +2655,7 @@ Index: src/userprog/syscall.c diff -u src/userprog/syscall.c~ src/userprog/syscall.c --- src/userprog/syscall.c 2005-06-18 20:21:21.000000000 -0700 +++ src/userprog/syscall.c 2006-05-18 21:26:51.000000000 -0700 -@@ -1,20 +1,594 @@ +@@ -1,20 +1,671 @@ #include "userprog/syscall.h" #include +#include @@ -2699,7 +2693,8 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c +static int sys_munmap (int mapping); +static int sys_chdir (const char *udir); +static int sys_mkdir (const char *udir); -+static int sys_lsdir (void); ++static int sys_readdir (int handle, char *name); ++static int sys_isdir (int handle); + static void syscall_handler (struct intr_frame *); - @@ -2744,7 +2739,8 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + {1, (syscall_function *) sys_munmap}, + {1, (syscall_function *) sys_chdir}, + {1, (syscall_function *) sys_mkdir}, -+ {0, (syscall_function *) sys_lsdir}, ++ {2, (syscall_function *) sys_readdir}, ++ {1, (syscall_function *) sys_isdir}, + }; + const struct syscall *sc; @@ -2794,6 +2790,32 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + } +} + ++/* Copies SIZE bytes from kernel address SRC to user address ++ UDST. ++ Call thread_exit() if any of the user accesses are invalid. */ ++static void ++copy_out (void *udst_, const void *src_, size_t size) ++{ ++ uint8_t *udst = udst_; ++ const uint8_t *src = src_; ++ ++ while (size > 0) ++ { ++ size_t chunk_size = PGSIZE - pg_ofs (udst); ++ if (chunk_size > size) ++ chunk_size = size; ++ ++ if (!page_lock (udst, false)) ++ thread_exit (); ++ memcpy (udst, src, chunk_size); ++ page_unlock (udst); ++ ++ udst += chunk_size; ++ src += chunk_size; ++ size -= chunk_size; ++ } ++} ++ +/* Creates a copy of user string US in kernel memory + and returns it as a page that must be freed with + palloc_free_page(). @@ -2903,6 +2925,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + { + struct list_elem elem; /* List element. */ + struct file *file; /* File. */ ++ struct dir *dir; /* Directory. */ + int handle; /* File handle. */ + }; + @@ -2914,18 +2937,28 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + struct file_descriptor *fd; + int handle = -1; + -+ fd = malloc (sizeof *fd); ++ fd = calloc (1, sizeof *fd); + if (fd != NULL) + { -+ fd->file = file_open (filesys_open (kfile)); -+ if (fd->file != NULL) ++ struct inode *inode = filesys_open (kfile); ++ if (inode != NULL) + { -+ struct thread *cur = thread_current (); -+ handle = fd->handle = cur->next_handle++; -+ list_push_front (&cur->fds, &fd->elem); ++ if (inode_get_type (inode) == FILE_INODE) ++ fd->file = file_open (inode); ++ else ++ fd->dir = dir_open (inode); ++ if (fd->file != NULL || fd->dir != NULL) ++ { ++ struct thread *cur = thread_current (); ++ handle = fd->handle = cur->next_handle++; ++ list_push_front (&cur->fds, &fd->elem); ++ } ++ else ++ { ++ free (fd); ++ inode_close (inode); ++ } + } -+ else -+ free (fd); + } + + palloc_free_page (kfile); @@ -2953,11 +2986,35 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + thread_exit (); +} + ++/* Returns the file descriptor associated with the given handle. ++ Terminates the process if HANDLE is not associated with an ++ open ordinary file. */ ++static struct file_descriptor * ++lookup_file_fd (int handle) ++{ ++ struct file_descriptor *fd = lookup_fd (handle); ++ if (fd->file == NULL) ++ thread_exit (); ++ return fd; ++} ++ ++/* Returns the file descriptor associated with the given handle. ++ Terminates the process if HANDLE is not associated with an ++ open directory. */ ++static struct file_descriptor * ++lookup_dir_fd (int handle) ++{ ++ struct file_descriptor *fd = lookup_fd (handle); ++ if (fd->dir == NULL) ++ thread_exit (); ++ return fd; ++} ++ +/* Filesize system call. */ +static int +sys_filesize (int handle) +{ -+ struct file_descriptor *fd = lookup_fd (handle); ++ struct file_descriptor *fd = lookup_file_fd (handle); + int size; + + size = file_length (fd->file); @@ -2975,7 +3032,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + + /* Look up file descriptor. */ + if (handle != STDIN_FILENO) -+ fd = lookup_fd (handle); ++ fd = lookup_file_fd (handle); + + while (size > 0) + { @@ -3035,7 +3092,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + + /* Lookup up file descriptor. */ + if (handle != STDOUT_FILENO) -+ fd = lookup_fd (handle); ++ fd = lookup_file_fd (handle); + + while (size > 0) + { @@ -3086,7 +3143,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c +sys_seek (int handle, unsigned position) +{ + if ((off_t) position >= 0) -+ file_seek (lookup_fd (handle)->file, position); ++ file_seek (lookup_file_fd (handle)->file, position); + return 0; +} + @@ -3094,7 +3151,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c +static int +sys_tell (int handle) +{ -+ return file_tell (lookup_fd (handle)->file); ++ return file_tell (lookup_file_fd (handle)->file); +} + +/* Close system call. */ @@ -3103,6 +3160,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c +{ + struct file_descriptor *fd = lookup_fd (handle); + file_close (fd->file); ++ dir_close (fd->dir); + list_remove (&fd->elem); + free (fd); + return 0; @@ -3157,7 +3215,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c +static int +sys_mmap (int handle, void *addr) +{ -+ struct file_descriptor *fd = lookup_fd (handle); ++ struct file_descriptor *fd = lookup_file_fd (handle); + struct mapping *m = malloc (sizeof *m); + size_t offset; + off_t length; @@ -3227,12 +3285,24 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + return ok; +} + -+/* Lsdir system call. */ ++/* Readdir system call. */ +static int -+sys_lsdir (void) ++sys_readdir (int handle, char *uname) +{ -+ dir_list (thread_current ()->wd); -+ return 0; ++ struct file_descriptor *fd = lookup_dir_fd (handle); ++ char name[NAME_MAX + 1]; ++ bool ok = dir_readdir (fd->dir, name); ++ if (ok) ++ copy_out (uname, name, strlen (name) + 1); ++ return ok; ++} ++ ++/* Isdir system call. */ ++static int ++sys_isdir (int handle) ++{ ++ struct file_descriptor *fd = lookup_fd (handle); ++ return fd->dir != NULL; +} + +/* On thread exit, close all open files and unmap all mappings. */ @@ -3247,6 +3317,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c + struct file_descriptor *fd = list_entry (e, struct file_descriptor, elem); + next = list_next (e); + file_close (fd->file); ++ dir_close (fd->dir); + free (fd); + } +