Browse Source

feat: vfs_open_proc for user space syscalls

greatbridf 2 years ago
parent
commit
eaa4c84140

+ 1 - 1
include/kernel/process.hpp

@@ -284,7 +284,7 @@ public:
         // TODO: file opening permissions check
         int open(const char* filename, uint32_t flags)
         {
-            auto* dentry = fs::vfs_open(filename);
+            auto* dentry = fs::vfs_open_proc(filename);
 
             if (!dentry) {
                 errno = ENOTFOUND;

+ 1 - 0
include/kernel/vfs.hpp

@@ -275,6 +275,7 @@ int vfs_stat(fs::vfs::dentry* ent, stat* stat);
 
 // @return pointer to the dentry if found, nullptr if not
 fs::vfs::dentry* vfs_open(const char* path);
+vfs::dentry* vfs_open_proc(const char* path);
 
 } // namespace fs
 

+ 1 - 1
include/types/elf.hpp

@@ -136,7 +136,7 @@ struct PACKED elf32_section_header_entry {
 };
 
 struct elf32_load_data {
-    const char* exec;
+    fs::inode* exec;
     const char* const* argv;
     const char* const* envp;
     int errcode;

+ 3 - 1
src/kernel/process.cpp

@@ -281,7 +281,9 @@ void NORETURN _kernel_init(void)
     const char* envp[] = { nullptr };
 
     types::elf::elf32_load_data d;
-    d.exec = "/mnt/init";
+    auto* dent = fs::vfs_open("/mnt/init");
+    assert(dent && dent->ind);
+    d.exec = dent->ind;
     d.argv = argv;
     d.envp = envp;
     d.system = false;

+ 20 - 3
src/kernel/syscall.cpp

@@ -18,6 +18,7 @@
 #include <types/elf.hpp>
 #include <types/lock.hpp>
 #include <types/status.h>
+#include <types/string.hpp>
 
 #define SYSCALL_HANDLERS_SIZE (128)
 syscall_handler syscall_handlers[SYSCALL_HANDLERS_SIZE];
@@ -139,17 +140,29 @@ int _syscall_sleep(interrupt_stack*)
     return 0;
 }
 
+void __temporary_recursive_get_path(types::string<>& path, const fs::vfs::dentry* dent)
+{
+    if (dent == fs::fs_root)
+        return;
+
+    __temporary_recursive_get_path(path, dent->parent);
+    path += '/';
+    path += dent->name;
+}
+
 int _syscall_chdir(interrupt_stack* data)
 {
     const char* path = reinterpret_cast<const char*>(data->s_regs.edi);
-    auto* dir = fs::vfs_open(path);
+    auto* dir = fs::vfs_open_proc(path);
     if (!dir)
         return -ENOENT;
 
     if (!dir->ind->flags.in.directory)
         return -ENOTDIR;
 
-    current_process->pwd = path;
+    auto& pwd = current_process->pwd;
+    pwd.clear();
+    __temporary_recursive_get_path(pwd, dir);
 
     return 0;
 }
@@ -164,10 +177,14 @@ int _syscall_execve(interrupt_stack* data)
     char* const* argv = reinterpret_cast<char* const*>(data->s_regs.esi);
     char* const* envp = reinterpret_cast<char* const*>(data->s_regs.edx);
 
+    auto* dent = fs::vfs_open_proc(exec);
+    if (!dent || !dent->ind)
+        return -ENOENT;
+
     types::elf::elf32_load_data d;
     d.argv = argv;
     d.envp = envp;
-    d.exec = exec;
+    d.exec = dent->ind;
     d.system = false;
 
     int ret = types::elf::elf32_load(&d);

+ 15 - 0
src/kernel/vfs.cpp

@@ -506,6 +506,11 @@ fs::vfs::dentry* fs::vfs_open(const char* path)
                 return cur;
             }
             if (path[n] == '/') {
+                if (n == 0) {
+                    ++path;
+                    continue;
+                }
+
                 cur = cur->find(string(path, n));
 
                 if (!cur)
@@ -544,6 +549,16 @@ int fs::vfs_stat(fs::vfs::dentry* ent, stat* stat)
 {
     return ent->ind->fs->inode_stat(ent, stat);
 }
+fs::vfs::dentry* fs::vfs_open_proc(const char* path)
+{
+    if (!path)
+        return nullptr;
+
+    if (path[0] == '/')
+        return fs::vfs_open(path);
+
+    return fs::vfs_open(types::string<>(current_process->pwd).append("/").append(path).c_str());
+}
 
 static types::list<fs::vfs*>* fs_es;
 

+ 4 - 10
src/types/elf.cpp

@@ -29,16 +29,10 @@ inline void _user_push(char** sp, const char* str)
 
 int types::elf::elf32_load(types::elf::elf32_load_data* d)
 {
-    auto* ent_exec = fs::vfs_open(d->exec);
-    if (!ent_exec) {
-        d->errcode = ENOENT;
-        return GB_FAILED;
-    }
-
     // TODO: detect file format
     types::elf::elf32_header hdr {};
     auto n_read = fs::vfs_read(
-        ent_exec->ind,
+        d->exec,
         (char*)&hdr,
         sizeof(types::elf::elf32_header),
         0, sizeof(types::elf::elf32_header));
@@ -52,7 +46,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     size_t shents_size = hdr.shentsize * hdr.shnum;
     auto* phents = new types::elf::elf32_program_header_entry[hdr.phnum];
     n_read = fs::vfs_read(
-        ent_exec->ind,
+        d->exec,
         (char*)phents,
         phents_size,
         hdr.phoff, phents_size);
@@ -67,7 +61,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
 
     auto* shents = new types::elf::elf32_section_header_entry[hdr.shnum];
     n_read = fs::vfs_read(
-        ent_exec->ind,
+        d->exec,
         (char*)shents,
         shents_size,
         hdr.shoff, shents_size);
@@ -115,7 +109,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
         auto ret = mmap(
             (char*)vaddr,
             phents[i].filesz + (phents[i].vaddr & 0xfff),
-            ent_exec->ind,
+            d->exec,
             fileoff,
             1,
             d->system);

+ 2 - 2
user-space-program/lazybox.c

@@ -128,7 +128,7 @@ const char* find_file_name(const char* path)
         if (*last == '/')
             break;
     }
-    return last + 1;
+    return last == path ? path : last + 1;
 }
 
 int parse_applet(const char* name)
@@ -159,7 +159,7 @@ run:
         return -1;
     }
 
-    if (type == 0 && offset == 1) {
+    if (type == 0 && offset == 1 && argv[1]) {
         name = argv[offset++];
         goto run;
     }