X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Ffilesys%2Fdirectory.c;h=030c1c9b0dbaf9b3a41a4decaadd7c76793b1d63;hp=5f7dd9ed002ee0bf16582c5a65b80306a8c1832c;hb=a03618133f7df0954802a470a4bee7674f7aed45;hpb=615bf3b3d2a8573ed6fb9ddc0055745e163ac999 diff --git a/src/filesys/directory.c b/src/filesys/directory.c index 5f7dd9e..030c1c9 100644 --- a/src/filesys/directory.c +++ b/src/filesys/directory.c @@ -10,12 +10,13 @@ struct dir { struct inode *inode; /* Backing store. */ + off_t pos; /* Current position. */ }; /* A single directory entry. */ struct dir_entry { - disk_sector_t inode_sector; /* Sector number of header. */ + block_sector_t inode_sector; /* Sector number of header. */ char name[NAME_MAX + 1]; /* Null terminated file name. */ bool in_use; /* In use or free? */ }; @@ -23,42 +24,45 @@ struct dir_entry /* Creates a directory with space for ENTRY_CNT entries in the given SECTOR. Returns true if successful, false on failure. */ bool -dir_create (disk_sector_t sector, size_t entry_cnt) +dir_create (block_sector_t sector, size_t entry_cnt) { return inode_create (sector, entry_cnt * sizeof (struct dir_entry)); } -/* Opens the directory in the given INODE, of which it takes - ownership, and sets *DIRP to the new directory or a null - pointer on failure. Return true if successful, false on - failure. */ -bool -dir_open (struct inode *inode, struct dir **dirp) +/* Opens and returns the directory for the given INODE, of which + it takes ownership. Returns a null pointer on failure. */ +struct dir * +dir_open (struct inode *inode) { - struct dir *dir = NULL; - - ASSERT (dirp != NULL); - - if (inode != NULL) + struct dir *dir = calloc (1, sizeof *dir); + if (inode != NULL && dir != NULL) { - dir = malloc (sizeof *dir); - if (dir != NULL) - dir->inode = inode; + dir->inode = inode; + dir->pos = 0; + return dir; + } + else + { + inode_close (inode); + free (dir); + return NULL; } - - *dirp = dir; - if (dir == NULL) - inode_close (inode); - return dir != NULL; } -/* Opens the root directory and sets *DIRP to it or to a null - pointer on failure. Return true if successful, false on - failure. */ -bool -dir_open_root (struct dir **dirp) +/* Opens the root directory and returns a directory for it. + Return true if successful, false on failure. */ +struct dir * +dir_open_root (void) { - return dir_open (inode_open (ROOT_DIR_SECTOR), dirp); + return dir_open (inode_open (ROOT_DIR_SECTOR)); +} + +/* Opens and returns a new directory for the same inode as DIR. + Returns a null pointer on failure. */ +struct dir * +dir_reopen (struct dir *dir) +{ + return dir_open (inode_reopen (dir->inode)); } /* Destroys DIR and frees associated resources. */ @@ -72,6 +76,13 @@ dir_close (struct dir *dir) } } +/* Returns the inode encapsulated by DIR. */ +struct inode * +dir_get_inode (struct dir *dir) +{ + return dir->inode; +} + /* Searches DIR for a file with the given NAME. If successful, returns true, sets *EP to the directory entry if EP is non-null, and sets *OFSP to the byte offset of the @@ -128,12 +139,12 @@ dir_lookup (const struct dir *dir, const char *name, Fails if NAME is invalid (i.e. too long) or a disk or memory error occurs. */ bool -dir_add (struct dir *dir, const char *name, disk_sector_t inode_sector) +dir_add (struct dir *dir, const char *name, block_sector_t inode_sector) { struct dir_entry e; off_t ofs; bool success = false; - + ASSERT (dir != NULL); ASSERT (name != NULL); @@ -204,15 +215,22 @@ dir_remove (struct dir *dir, const char *name) return success; } -/* Prints the names of the files in DIR to the system console. */ -void -dir_list (const struct dir *dir) +/* Reads the next directory entry in DIR and stores the name in + NAME. Returns true if successful, false if the directory + contains no more entries. */ +bool +dir_readdir (struct dir *dir, char name[NAME_MAX + 1]) { struct dir_entry e; - size_t ofs; - - 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); + return true; + } + } + return false; }