From b959e7b0935318af0eca01a64ee13915b6ba5364 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 20 Nov 2023 23:32:19 -0800 Subject: [PATCH] support . and .. search in find_entry, add init_entry for fake root --- include/direntry.h | 2 ++ lib/direntry.cpp | 45 ++++++++++++++++++++++++++++++++++++++------- test/dir_API.cpp | 25 ++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/include/direntry.h b/include/direntry.h index ff4792d..be06514 100644 --- a/include/direntry.h +++ b/include/direntry.h @@ -33,6 +33,8 @@ typedef struct treeNode { FileNode *self_info; //self fileNode infromation } TreeNode; +/*for root*/ +TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode *new_inode); /*root directory have its own initialization, so parent wont be NULL*/ int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode *new_inode); /*if want to use dir mode use the subdirectory treeNode pointer */ diff --git a/lib/direntry.cpp b/lib/direntry.cpp index 12eb1c9..0d11546 100644 --- a/lib/direntry.cpp +++ b/lib/direntry.cpp @@ -127,6 +127,20 @@ void freeTree(TreeNode *node) { /*********************************Direntry operation****************************************** ********************************************************************************************/ +//for fake root (mount point) +TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode *new_inode) { + TreeNode *newDir = (TreeNode *)malloc(sizeof(TreeNode)); + newDir->dirName = strdup(fileName); + newDir->contents = createHashTable(20);//hashSize define 20 + newDir->parent = newDir; + FileNode *newFile = (FileNode *)malloc(sizeof(FileNode)); + newFile->name = strdup(fileName); + newFile->inode_number = new_inode_number; + newFile->permissions = new_inode->permissions; + newDir->self_info = newFile; + return newDir; +} + int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode *new_inode){ char *Name = strdup(fileName); TreeNode *newDir = NULL; @@ -156,17 +170,34 @@ FileNode *fischl_find_entry(TreeNode *root, const char *path){ FileNode *file = NULL; while (segment != NULL && current != NULL) { - file = lookupHash(current->contents, segment); - if (file != NULL && file->subdirectory == NULL) { - free(pathCopy); - return file; //File found - //return current; return filenode + if (strcmp(segment, "..") == 0) { + // Move up to the parent directory + current = current->parent; + if (current == NULL) { + // If there's no parent, we've reached the top of the tree, but root itself is same + break; + } + } else if (strcmp(segment, ".") == 0) { + // Stay in the current directory (no action needed) + } + else{ + file = lookupHash(current->contents, segment); + if (file != NULL && file->subdirectory == NULL) { + free(pathCopy); + return file; //File found + //return current; return filenode + } + current = file ? file->subdirectory : NULL; } - current = file ? file->subdirectory : NULL; segment = strtok(NULL, "/"); } free(pathCopy); + + if (current != NULL && file == NULL) { + // If we've stopped at a directory and not a file, return the directory's self info + return current->self_info; + } + return file; // NULL if not found - //return current; return filenode } \ No newline at end of file diff --git a/test/dir_API.cpp b/test/dir_API.cpp index fb93b31..2d2b2a4 100644 --- a/test/dir_API.cpp +++ b/test/dir_API.cpp @@ -12,19 +12,25 @@ #include "direntry.h" int main() { - TreeNode *root = createDirectory("/", NULL, 20); + //Init fake root directory + INode inode_root; + u_int64_t file_permissions = 0; + inode_root.permissions = file_permissions | S_IFDIR; + TreeNode *root = fischl_init_entry(0, "/", &inode_root);//0 is inode number assigned by inode_allocate() + //add file or dir under fake root INode inode_file1; fischl_add_entry(root, 2, "file1",&inode_file1); //I will put this function in create_new_inode function, there will inode number(2) when inode_allocate INode inode_dir1; //permission is necessary there to create treeNode or not - u_int64_t ddd_permissions = 0; - inode_dir1.permissions = ddd_permissions | S_IFDIR; + file_permissions = 0; + inode_dir1.permissions = file_permissions | S_IFDIR; fischl_add_entry(root, 3, "dir1",&inode_dir1); //find dir file (from root directory view, root contains dir1/ subdirectory) FileNode *get_dir1 = fischl_find_entry(root,"/dir1/"); if(get_dir1 == NULL){ printf("No dir1 under %s\n",root->dirName); + freeTree(root); return -1; }else{ fprintf(stderr,"[%s ,%d]",__func__,__LINE__); @@ -54,6 +60,7 @@ int main() { get_file2 = fischl_find_entry(root,"/dir1/file2"); if(get_file2 == NULL){ printf("No dir1 under dir1\n"); + freeTree(root); return -1; }else{ fprintf(stderr,"[%s ,%d]",__func__,__LINE__); @@ -63,6 +70,7 @@ int main() { get_file2 = fischl_find_entry(get_dir1->subdirectory,"/file2"); if(get_file2 == NULL){ printf("No dir1 under %s\n",get_dir1->subdirectory->dirName); + freeTree(root); return -1; }else{ fprintf(stderr,"[%s ,%d]",__func__,__LINE__); @@ -80,10 +88,21 @@ int main() { get_file3 = fischl_find_entry(get_dir1_tree,"/file3"); if(get_file3 == NULL){ printf("No dir1 under %s\n",get_dir1_tree->dirName); + freeTree(root); return -1; }else{ printf(" %s under %s\n",get_file3->name,get_dir1_tree->dirName); } + FileNode *get_file1 = NULL;//under root + //use .. to find + get_file1 = fischl_find_entry(get_dir1_tree,"../file1"); + if(get_file1 == NULL){ + printf("No file1\n"); + freeTree(root); + return -1; + }else{ + printf(" %s under root(..)\n",get_file1->name); + } // Cleanup freeTree(root);