mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 06:02:44 +00:00 
			
		
		
		
	Implement sys$chdir() and teach sh+ls to cd around and browse different dirs.
This commit is contained in:
		
							parent
							
								
									ac738b03d6
								
							
						
					
					
						commit
						2749e7f1c2
					
				
					 16 changed files with 147 additions and 33 deletions
				
			
		|  | @ -110,6 +110,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) | ||||||
|         return 0; |         return 0; | ||||||
|     case Syscall::GetArguments: |     case Syscall::GetArguments: | ||||||
|         return current->sys$get_arguments((int*)arg1, (char***)arg2); |         return current->sys$get_arguments((int*)arg1, (char***)arg2); | ||||||
|  |     case Syscall::PosixChdir: | ||||||
|  |         return current->sys$chdir((const char*)arg1); | ||||||
|     default: |     default: | ||||||
|         kprintf("int0x80: Unknown function %x requested {%x, %x, %x}\n", function, arg1, arg2, arg3); |         kprintf("int0x80: Unknown function %x requested {%x, %x, %x}\n", function, arg1, arg2, arg3); | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ enum Function { | ||||||
|     PosixGettimeofday = 0x2000, |     PosixGettimeofday = 0x2000, | ||||||
|     PosixGethostname = 0x2001, |     PosixGethostname = 0x2001, | ||||||
|     GetArguments = 0x2002, |     GetArguments = 0x2002, | ||||||
|  |     PosixChdir = 0x2003, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void initialize(); | void initialize(); | ||||||
|  |  | ||||||
|  | @ -205,7 +205,14 @@ Task* Task::createUserTask(const String& path, uid_t uid, gid_t gid, pid_t paren | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto handle = VirtualFileSystem::the().open(path); |     RetainPtr<VirtualFileSystem::Node> cwd; | ||||||
|  |     { | ||||||
|  |         InterruptDisabler disabler; | ||||||
|  |         if (auto* parentTask = Task::fromPID(parentPID)) | ||||||
|  |             cwd = parentTask->m_cwd.copyRef(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto handle = VirtualFileSystem::the().open(path, cwd.ptr()); | ||||||
|     if (!handle) { |     if (!handle) { | ||||||
|         error = -ENOENT; // FIXME: Get a more detailed error from VFS.
 |         error = -ENOENT; // FIXME: Get a more detailed error from VFS.
 | ||||||
|         return nullptr; |         return nullptr; | ||||||
|  | @ -327,9 +334,9 @@ Task::Task(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel ring) | ||||||
| 
 | 
 | ||||||
|     auto* parentTask = Task::fromPID(parentPID); |     auto* parentTask = Task::fromPID(parentPID); | ||||||
|     if (parentTask) |     if (parentTask) | ||||||
|         m_cwd = parentTask->m_cwd; |         m_cwd = parentTask->m_cwd.copyRef(); | ||||||
|     else |     else | ||||||
|         m_cwd = "/"; |         m_cwd = nullptr; | ||||||
| 
 | 
 | ||||||
|     m_nextRegion = LinearAddress(0x600000); |     m_nextRegion = LinearAddress(0x600000); | ||||||
| 
 | 
 | ||||||
|  | @ -712,22 +719,29 @@ int Task::sys$close(int fd) | ||||||
| 
 | 
 | ||||||
| int Task::sys$lstat(const char* path, void* statbuf) | int Task::sys$lstat(const char* path, void* statbuf) | ||||||
| { | { | ||||||
|     auto handle = VirtualFileSystem::the().open(move(path)); |     auto handle = VirtualFileSystem::the().open(move(path), m_cwd.ptr()); | ||||||
|     if (!handle) |     if (!handle) | ||||||
|         return -1; |         return -1; | ||||||
|     handle->stat((Unix::stat*)statbuf); |     handle->stat((Unix::stat*)statbuf); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int Task::sys$chdir(const char* path) | ||||||
|  | { | ||||||
|  |     auto handle = VirtualFileSystem::the().open(path, m_cwd.ptr()); | ||||||
|  |     if (!handle) | ||||||
|  |         return -ENOENT; // FIXME: More detailed error.
 | ||||||
|  |     if (!handle->isDirectory()) | ||||||
|  |         return -ENOTDIR; | ||||||
|  |     m_cwd = handle->vnode(); | ||||||
|  |     kprintf("m_cwd <- %p (%u)\n", m_cwd.ptr(), handle->vnode()->inode.index()); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int Task::sys$getcwd(char* buffer, size_t size) | int Task::sys$getcwd(char* buffer, size_t size) | ||||||
| { | { | ||||||
|     if (size < m_cwd.length() + 1) { |     // FIXME: Implement!
 | ||||||
|         // FIXME: return -ERANGE;
 |     return -ENOTIMPL; | ||||||
|         return -1; |  | ||||||
|     } |  | ||||||
|     memcpy(buffer, m_cwd.characters(), m_cwd.length()); |  | ||||||
|     buffer[m_cwd.length()] = '\0'; |  | ||||||
|     return 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int Task::sys$open(const char* path, size_t pathLength) | int Task::sys$open(const char* path, size_t pathLength) | ||||||
|  | @ -744,7 +758,7 @@ int Task::sys$open(const char* path, size_t pathLength) | ||||||
| 
 | 
 | ||||||
| FileHandle* Task::openFile(String&& path) | FileHandle* Task::openFile(String&& path) | ||||||
| { | { | ||||||
|     auto handle = VirtualFileSystem::the().open(move(path)); |     auto handle = VirtualFileSystem::the().open(move(path), m_cwd.ptr()); | ||||||
|     if (!handle) { |     if (!handle) { | ||||||
| #ifdef DEBUG_IO | #ifdef DEBUG_IO | ||||||
|         kprintf("vfs::open() failed\n"); |         kprintf("vfs::open() failed\n"); | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| #include "TSS.h" | #include "TSS.h" | ||||||
| #include <AK/Vector.h> | #include <AK/Vector.h> | ||||||
| #include "i386.h" | #include "i386.h" | ||||||
|  | #include <VirtualFileSystem/VirtualFileSystem.h> | ||||||
| 
 | 
 | ||||||
| //#define TASK_SANITY_CHECKS
 | //#define TASK_SANITY_CHECKS
 | ||||||
| 
 | 
 | ||||||
|  | @ -98,6 +99,7 @@ public: | ||||||
|     int sys$munmap(void*, size_t size); |     int sys$munmap(void*, size_t size); | ||||||
|     int sys$get_dir_entries(int fd, void*, size_t); |     int sys$get_dir_entries(int fd, void*, size_t); | ||||||
|     int sys$getcwd(char*, size_t); |     int sys$getcwd(char*, size_t); | ||||||
|  |     int sys$chdir(const char*); | ||||||
|     int sys$sleep(unsigned seconds); |     int sys$sleep(unsigned seconds); | ||||||
|     int sys$gettimeofday(timeval*); |     int sys$gettimeofday(timeval*); | ||||||
|     int sys$gethostname(char* name, size_t length); |     int sys$gethostname(char* name, size_t length); | ||||||
|  | @ -150,7 +152,7 @@ private: | ||||||
|     pid_t m_waitee { -1 }; |     pid_t m_waitee { -1 }; | ||||||
|     int m_fdBlockedOnRead { -1 }; |     int m_fdBlockedOnRead { -1 }; | ||||||
| 
 | 
 | ||||||
|     String m_cwd; |     RetainPtr<VirtualFileSystem::Node> m_cwd; | ||||||
| 
 | 
 | ||||||
|     struct Region { |     struct Region { | ||||||
|         Region(LinearAddress, size_t, RetainPtr<Zone>&&, String&&); |         Region(LinearAddress, size_t, RetainPtr<Zone>&&, String&&); | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -37,3 +37,5 @@ | ||||||
| #define ENAMETOOLONG 36 // Name too long
 | #define ENAMETOOLONG 36 // Name too long
 | ||||||
| 
 | 
 | ||||||
| #define EOVERFLOW 75    // Value too large for defined data type
 | #define EOVERFLOW 75    // Value too large for defined data type
 | ||||||
|  | 
 | ||||||
|  | #define ENOTIMPL 999    // Not implemented
 | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ dirent* readdir(DIR* dirp) | ||||||
|         dirp->nextptr = dirp->buffer; |         dirp->nextptr = dirp->buffer; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (dirp->nextptr > (dirp->buffer + dirp->buffer_size)) |     if (dirp->nextptr >= (dirp->buffer + dirp->buffer_size)) | ||||||
|         return nullptr; |         return nullptr; | ||||||
| 
 | 
 | ||||||
|     auto* sys_ent = (sys_dirent*)dirp->nextptr; |     auto* sys_ent = (sys_dirent*)dirp->nextptr; | ||||||
|  |  | ||||||
|  | @ -69,6 +69,7 @@ const char* strerror(int errnum) | ||||||
|     case ERANGE: return "Math result not representable"; |     case ERANGE: return "Math result not representable"; | ||||||
|     case ENAMETOOLONG: return "Name too long"; |     case ENAMETOOLONG: return "Name too long"; | ||||||
|     case EOVERFLOW: return "Value too large for data type"; |     case EOVERFLOW: return "Value too large for data type"; | ||||||
|  |     case ENOTIMPL: return "Not implemented"; | ||||||
|     } |     } | ||||||
|     printf("strerror() missing string for errnum=%d\n", errnum); |     printf("strerror() missing string for errnum=%d\n", errnum); | ||||||
|     return "Unknown error"; |     return "Unknown error"; | ||||||
|  |  | ||||||
|  | @ -51,6 +51,12 @@ int lstat(const char* path, stat* statbuf) | ||||||
|     __RETURN_WITH_ERRNO(rc, rc, -1); |     __RETURN_WITH_ERRNO(rc, rc, -1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int chdir(const char* path) | ||||||
|  | { | ||||||
|  |     int rc = Syscall::invoke(Syscall::PosixChdir, (dword)path); | ||||||
|  |     __RETURN_WITH_ERRNO(rc, rc, -1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| char* getcwd(char* buffer, size_t size) | char* getcwd(char* buffer, size_t size) | ||||||
| { | { | ||||||
|     int rc = Syscall::invoke(Syscall::PosixGetcwd, (dword)buffer, (dword)size); |     int rc = Syscall::invoke(Syscall::PosixGetcwd, (dword)buffer, (dword)size); | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ int open(const char* path); | ||||||
| ssize_t read(int fd, void* buf, size_t count); | ssize_t read(int fd, void* buf, size_t count); | ||||||
| int close(int fd); | int close(int fd); | ||||||
| pid_t waitpid(pid_t); | pid_t waitpid(pid_t); | ||||||
|  | int chdir(const char* path); | ||||||
| char* getcwd(char* buffer, size_t size); | char* getcwd(char* buffer, size_t size); | ||||||
| int lstat(const char* path, stat* statbuf); | int lstat(const char* path, stat* statbuf); | ||||||
| int sleep(unsigned seconds); | int sleep(unsigned seconds); | ||||||
|  |  | ||||||
|  | @ -4,14 +4,14 @@ | ||||||
| 
 | 
 | ||||||
| int main(int c, char** v) | int main(int c, char** v) | ||||||
| { | { | ||||||
|     DIR* dirp = opendir("/"); |     DIR* dirp = opendir("."); | ||||||
|     if (!dirp) { |     if (!dirp) { | ||||||
|         printf("opendir failed :(\n"); |         printf("opendir failed :(\n"); | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|     char pathbuf[256]; |     char pathbuf[256]; | ||||||
|     while (auto* de = readdir(dirp)) { |     while (auto* de = readdir(dirp)) { | ||||||
|         sprintf(pathbuf, "/%s", de->d_name); |         sprintf(pathbuf, "%s", de->d_name); | ||||||
|         stat st; |         stat st; | ||||||
|         int rc = lstat(pathbuf, &st); |         int rc = lstat(pathbuf, &st); | ||||||
|         if (rc == -1) { |         if (rc == -1) { | ||||||
|  |  | ||||||
|  | @ -3,6 +3,9 @@ | ||||||
| #include <LibC/process.h> | #include <LibC/process.h> | ||||||
| #include <LibC/errno.h> | #include <LibC/errno.h> | ||||||
| #include <LibC/string.h> | #include <LibC/string.h> | ||||||
|  | #include <LibC/stdlib.h> | ||||||
|  | 
 | ||||||
|  | char* g_cwd = nullptr; | ||||||
| 
 | 
 | ||||||
| static void prompt() | static void prompt() | ||||||
| { | { | ||||||
|  | @ -12,12 +15,63 @@ static void prompt() | ||||||
|         printf("$ "); |         printf("$ "); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int sh_pwd(int, const char**) | ||||||
|  | { | ||||||
|  |     printf("cwd: %s\n", g_cwd); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int sh_cd(int argc, const char** argv) | ||||||
|  | { | ||||||
|  |     if (argc == 1) { | ||||||
|  |         printf("usage: cd <path>\n"); | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     char pathbuf[128]; | ||||||
|  |     if (argv[1][1] == '/') | ||||||
|  |         memcpy(pathbuf, argv[1], strlen(argv[1])); | ||||||
|  |     else | ||||||
|  |         sprintf(pathbuf, "%s/%s", g_cwd, argv[1]); | ||||||
|  |     struct stat st; | ||||||
|  |     int rc = lstat(pathbuf, &st); | ||||||
|  |     if (rc < 0) { | ||||||
|  |         printf("lstat(%s) failed: %s\n", pathbuf, strerror(errno)); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     if (!S_ISDIR(st.st_mode)) { | ||||||
|  |         printf("Not a directory: %s\n", pathbuf); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     rc = chdir(pathbuf); | ||||||
|  |     if (rc < 0) { | ||||||
|  |         printf("chdir(%s) failed: %s\n", pathbuf, strerror(errno)); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     memcpy(g_cwd, pathbuf, strlen(pathbuf)); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static bool handle_builtin(int argc, const char** argv, int& retval) | ||||||
|  | { | ||||||
|  |     if (argc == 0) | ||||||
|  |         return false; | ||||||
|  |     if (!strcmp(argv[0], "cd")) { | ||||||
|  |         retval = sh_cd(argc, argv); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     if (!strcmp(argv[0], "pwd")) { | ||||||
|  |         retval = sh_pwd(argc, argv); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int runcmd(char* cmd) | static int runcmd(char* cmd) | ||||||
| { | { | ||||||
|     if (cmd[0] == 0) |     if (cmd[0] == 0) | ||||||
|         return 0; |         return 0; | ||||||
|     char buf[128]; |     char buf[128]; | ||||||
|     sprintf(buf, "/bin/%s", cmd); |     memcpy(buf, cmd, 128); | ||||||
| 
 | 
 | ||||||
|     const char* argv[32]; |     const char* argv[32]; | ||||||
|     size_t argi = 1; |     size_t argi = 1; | ||||||
|  | @ -30,16 +84,27 @@ static int runcmd(char* cmd) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     argv[argi + 1] = nullptr; |     argv[argi + 1] = nullptr; | ||||||
|     int ret = spawn(argv[0], argv); | 
 | ||||||
|  |     int retval = 0; | ||||||
|  |     if (handle_builtin(argi, argv, retval)) { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const char* search_path = "/bin"; | ||||||
|  | 
 | ||||||
|  |     char pathbuf[128]; | ||||||
|  |     sprintf(pathbuf, "%s/%s", search_path, argv[0]); | ||||||
|  |     int ret = spawn(pathbuf, argv); | ||||||
|     if (ret == -1) { |     if (ret == -1) { | ||||||
|         printf("spawn failed: %s (%s)\n", cmd, strerror(errno)); |         printf("spawn failed: %s (%s)\n", cmd, strerror(errno)); | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |     // FIXME: waitpid should give us the spawned process's exit status
 | ||||||
|     waitpid(ret); |     waitpid(ret); | ||||||
|     return 0; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int main(int c, char** v) | int main(int, char**) | ||||||
| { | { | ||||||
|     char linebuf[128]; |     char linebuf[128]; | ||||||
|     int linedx = 0; |     int linedx = 0; | ||||||
|  | @ -50,6 +115,9 @@ int main(int c, char** v) | ||||||
|         printf("failed to open /dev/keyboard :(\n"); |         printf("failed to open /dev/keyboard :(\n"); | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |     g_cwd = (char*)malloc(1024); | ||||||
|  |     g_cwd[0] = '/'; | ||||||
|  |     g_cwd[1] = '\0'; | ||||||
|     prompt(); |     prompt(); | ||||||
|     for (;;) { |     for (;;) { | ||||||
|         char keybuf[16]; |         char keybuf[16]; | ||||||
|  |  | ||||||
|  | @ -128,6 +128,11 @@ ByteBuffer FileHandle::readEntireFile() | ||||||
|     return m_vnode->fileSystem()->readEntireInode(m_vnode->inode); |     return m_vnode->fileSystem()->readEntireInode(m_vnode->inode); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool FileHandle::isDirectory() const | ||||||
|  | { | ||||||
|  |     return m_vnode->metadata().isDirectory(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| ssize_t FileHandle::get_dir_entries(byte* buffer, size_t size) | ssize_t FileHandle::get_dir_entries(byte* buffer, size_t size) | ||||||
| { | { | ||||||
|     Locker locker(VirtualFileSystem::lock()); |     Locker locker(VirtualFileSystem::lock()); | ||||||
|  |  | ||||||
|  | @ -20,6 +20,10 @@ public: | ||||||
| 
 | 
 | ||||||
|     String absolutePath() const; |     String absolutePath() const; | ||||||
| 
 | 
 | ||||||
|  |     bool isDirectory() const; | ||||||
|  | 
 | ||||||
|  |     VirtualFileSystem::Node* vnode() { return m_vnode.ptr(); } | ||||||
|  | 
 | ||||||
| #ifdef SERENITY | #ifdef SERENITY | ||||||
|     int fd() const { return m_fd; } |     int fd() const { return m_fd; } | ||||||
|     void setFD(int fd) { m_fd = fd; } |     void setFD(int fd) { m_fd = fd; } | ||||||
|  |  | ||||||
|  | @ -168,9 +168,9 @@ void VirtualFileSystem::freeNode(Node* node) | ||||||
|     m_nodeFreeList.append(move(node)); |     m_nodeFreeList.append(move(node)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool VirtualFileSystem::isDirectory(const String& path) | bool VirtualFileSystem::isDirectory(const String& path, Node* base) | ||||||
| { | { | ||||||
|     auto inode = resolvePath(path); |     auto inode = resolvePath(path, base); | ||||||
|     if (!inode.isValid()) |     if (!inode.isValid()) | ||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|  | @ -355,11 +355,11 @@ bool VirtualFileSystem::touch(const String& path) | ||||||
|     return inode.fileSystem()->setModificationTime(inode, ktime(nullptr)); |     return inode.fileSystem()->setModificationTime(inode, ktime(nullptr)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| OwnPtr<FileHandle> VirtualFileSystem::open(const String& path) | OwnPtr<FileHandle> VirtualFileSystem::open(const String& path, Node* base) | ||||||
| { | { | ||||||
|     Locker locker(VirtualFileSystem::lock()); |     Locker locker(VirtualFileSystem::lock()); | ||||||
| 
 | 
 | ||||||
|     auto inode = resolvePath(path); |     auto inode = resolvePath(path, base); | ||||||
|     if (!inode.isValid()) |     if (!inode.isValid()) | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     auto vnode = getOrCreateNode(inode); |     auto vnode = getOrCreateNode(inode); | ||||||
|  | @ -368,7 +368,7 @@ OwnPtr<FileHandle> VirtualFileSystem::open(const String& path) | ||||||
|     return make<FileHandle>(move(vnode)); |     return make<FileHandle>(move(vnode)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| OwnPtr<FileHandle> VirtualFileSystem::create(const String& path) | OwnPtr<FileHandle> VirtualFileSystem::create(const String& path, Node* base) | ||||||
| { | { | ||||||
|     Locker locker(VirtualFileSystem::lock()); |     Locker locker(VirtualFileSystem::lock()); | ||||||
| 
 | 
 | ||||||
|  | @ -378,7 +378,7 @@ OwnPtr<FileHandle> VirtualFileSystem::create(const String& path) | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| OwnPtr<FileHandle> VirtualFileSystem::mkdir(const String& path) | OwnPtr<FileHandle> VirtualFileSystem::mkdir(const String& path, Node* base) | ||||||
| { | { | ||||||
|     Locker locker(VirtualFileSystem::lock()); |     Locker locker(VirtualFileSystem::lock()); | ||||||
| 
 | 
 | ||||||
|  | @ -398,10 +398,18 @@ InodeIdentifier VirtualFileSystem::resolveSymbolicLink(const String& basePath, I | ||||||
|     return resolvePath(buf); |     return resolvePath(buf); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| InodeIdentifier VirtualFileSystem::resolvePath(const String& path) | InodeIdentifier VirtualFileSystem::resolvePath(const String& path, Node* base) | ||||||
| { | { | ||||||
|  |     if (path.isEmpty()) | ||||||
|  |         return { }; | ||||||
|  | 
 | ||||||
|     auto parts = path.split('/'); |     auto parts = path.split('/'); | ||||||
|     InodeIdentifier inode = m_rootNode->inode; |     InodeIdentifier inode; | ||||||
|  | 
 | ||||||
|  |     if (path[0] == '/') | ||||||
|  |         inode = m_rootNode->inode; | ||||||
|  |     else | ||||||
|  |         inode = base ? base->inode : m_rootNode->inode; | ||||||
| 
 | 
 | ||||||
|     for (unsigned i = 0; i < parts.size(); ++i) { |     for (unsigned i = 0; i < parts.size(); ++i) { | ||||||
|         auto& part = parts[i]; |         auto& part = parts[i]; | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ public: | ||||||
|     VirtualFileSystem(); |     VirtualFileSystem(); | ||||||
|     ~VirtualFileSystem(); |     ~VirtualFileSystem(); | ||||||
| 
 | 
 | ||||||
|     bool isDirectory(const String& path); |     bool isDirectory(const String& path, Node* base = nullptr); | ||||||
|     void listDirectory(const String& path); |     void listDirectory(const String& path); | ||||||
|     void listDirectoryRecursively(const String& path); |     void listDirectoryRecursively(const String& path); | ||||||
| 
 | 
 | ||||||
|  | @ -64,9 +64,9 @@ public: | ||||||
|     bool mountRoot(RetainPtr<FileSystem>&&); |     bool mountRoot(RetainPtr<FileSystem>&&); | ||||||
|     bool mount(RetainPtr<FileSystem>&&, const String& path); |     bool mount(RetainPtr<FileSystem>&&, const String& path); | ||||||
| 
 | 
 | ||||||
|     OwnPtr<FileHandle> open(const String& path); |     OwnPtr<FileHandle> open(const String& path, Node* base = nullptr); | ||||||
|     OwnPtr<FileHandle> create(const String& path); |     OwnPtr<FileHandle> create(const String& path, Node* base = nullptr); | ||||||
|     OwnPtr<FileHandle> mkdir(const String& path); |     OwnPtr<FileHandle> mkdir(const String& path, Node* base = nullptr); | ||||||
| 
 | 
 | ||||||
|     bool isRoot(InodeIdentifier) const; |     bool isRoot(InodeIdentifier) const; | ||||||
| 
 | 
 | ||||||
|  | @ -79,7 +79,7 @@ private: | ||||||
| 
 | 
 | ||||||
|     void enumerateDirectoryInode(InodeIdentifier, Function<bool(const FileSystem::DirectoryEntry&)>); |     void enumerateDirectoryInode(InodeIdentifier, Function<bool(const FileSystem::DirectoryEntry&)>); | ||||||
|     String absolutePath(InodeIdentifier); |     String absolutePath(InodeIdentifier); | ||||||
|     InodeIdentifier resolvePath(const String& path); |     InodeIdentifier resolvePath(const String& path, Node* base = nullptr); | ||||||
|     InodeIdentifier resolveSymbolicLink(const String& basePath, InodeIdentifier symlinkInode); |     InodeIdentifier resolveSymbolicLink(const String& basePath, InodeIdentifier symlinkInode); | ||||||
| 
 | 
 | ||||||
|     RetainPtr<Node> allocateNode(); |     RetainPtr<Node> allocateNode(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling