1 #include "filesys/directory.h"
4 #include "filesys/file.h"
5 #include "filesys/fsutil.h"
6 #include "threads/malloc.h"
11 size_t entry_cnt; /* Number of entries. */
12 struct dir_entry *entries; /* Array of entries. */
15 /* A single directory entry. */
18 bool in_use; /* In use or free? */
19 char name[NAME_MAX + 1]; /* Null terminated file name. */
20 disk_sector_t inode_sector; /* Sector number of header. */
23 /* Returns a new directory that holds ENTRY_CNT entries, if
24 successful, or a null pointer if memory is unavailable. */
26 dir_create (size_t entry_cnt)
28 struct dir *d = malloc (sizeof *d);
31 d->entry_cnt = entry_cnt;
32 d->entries = calloc (1, sizeof *d->entries * entry_cnt);
33 if (d->entries != NULL)
40 /* Returns the size, in bytes, of a directory with ENTRY_CNT
43 dir_size (size_t entry_cnt)
45 return entry_cnt * sizeof (struct dir_entry);
48 /* Destroys D and frees associated resources. */
50 dir_destroy (struct dir *d)
60 D must have already been initialized, to the correct number of
61 entries, with dir_init(). */
63 dir_read (struct dir *d, struct file *file)
66 ASSERT (file != NULL);
67 ASSERT (file_length (file) >= (off_t) dir_size (d->entry_cnt));
69 file_read_at (file, d->entries, dir_size (d->entry_cnt), 0);
73 D must have already been initialized, to the correct number of
74 entries, with dir_init(). */
76 dir_write (struct dir *d, struct file *file)
78 file_write_at (file, d->entries, dir_size (d->entry_cnt), 0);
81 /* Searches D for a file named NAME.
82 If successful, returns the file's entry;
83 otherwise, returns a null pointer. */
84 static struct dir_entry *
85 lookup (const struct dir *d, const char *name)
90 ASSERT (name != NULL);
92 if (strlen (name) > NAME_MAX)
95 for (i = 0; i < d->entry_cnt; i++)
97 struct dir_entry *e = &d->entries[i];
98 if (e->in_use && !strcmp (name, e->name))
104 /* Searches D for a file named NAME
105 and returns true if one exists, false otherwise.
106 If INODE_SECTOR is nonnull, then on success *INODE_SECTOR
107 is set to the sector that contains the file's inode. */
109 dir_lookup (const struct dir *d, const char *name,
110 disk_sector_t *inode_sector)
112 const struct dir_entry *e;
115 ASSERT (name != NULL);
117 e = lookup (d, name);
120 if (inode_sector != NULL)
121 *inode_sector = e->inode_sector;
128 /* Adds a file named NAME to D, which must not already contain a
129 file by that name. The file's inode is in sector
131 Returns true if successful, false on failure.
132 Fails if NAME is invalid (i.e. too long) or if D has no free
133 directory entries. */
135 dir_add (struct dir *d, const char *name, disk_sector_t inode_sector)
140 ASSERT (name != NULL);
141 ASSERT (lookup (d, name) == NULL);
143 if (strlen (name) > NAME_MAX)
146 for (i = 0; i < d->entry_cnt; i++)
148 struct dir_entry *e = &d->entries[i];
152 strlcpy (e->name, name, sizeof e->name);
153 e->inode_sector = inode_sector;
160 /* Removes any entry for NAME in D.
161 Returns true if successful, false on failure,
162 which occurs only if there is no file with the given NAME. */
164 dir_remove (struct dir *d, const char *name)
169 ASSERT (name != NULL);
171 e = lookup (d, name);
181 /* Prints the names of the files in D to the system console. */
183 dir_list (const struct dir *d)
187 for (e = d->entries; e < d->entries + d->entry_cnt; e++)
189 printf ("%s\n", e->name);
192 /* Dumps the contents of D, including its files' names and their
193 contents, to the system console. */
195 dir_dump (const struct dir *d)
199 for (e = d->entries; e < d->entries + d->entry_cnt; e++)
202 printf ("Contents of %s:\n", e->name);
203 fsutil_print (e->name);