From 48de0cd029b52f64f76345b6e1fdf3cde5c58de3 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 23 Oct 2009 19:40:08 +0200 Subject: More work on syscalls and shell --- Source/Applications/Shell/Makefile | 3 +- Source/Applications/Shell/Shell-fs.ns.cpp | 52 ++++++++++++++++++++++++++ Source/Applications/Shell/Shell.ns.cpp | 32 ++++++++++++++-- Source/Applications/Shell/Shell.ns.h | 3 ++ Source/Kernel/Core/kmain.wtf.cpp | 1 + Source/Kernel/Makefile | 2 +- Source/Kernel/Shell/KernelShell.class.cpp | 2 - Source/Kernel/SyscallManager/Res.ns.h | 10 +++++ Source/Kernel/TaskManager/Process.class.cpp | 1 + Source/Kernel/TaskManager/Process.class.h | 5 +++ Source/Kernel/VFS/DirectoryNode.class.cpp | 19 ++++++++++ Source/Kernel/VFS/DirectoryNode.class.h | 9 ++++- Source/Kernel/VFS/FSNode-sc.proto.cpp | 19 ++++++++++ Source/Kernel/VFS/FSNode.proto.h | 1 + Source/Library/Interface/FSNode.iface.h | 6 +++ Source/Library/Userland/Binding/FSNode.class.h | 20 +++++++++- 16 files changed, 176 insertions(+), 9 deletions(-) create mode 100644 Source/Applications/Shell/Shell-fs.ns.cpp (limited to 'Source') diff --git a/Source/Applications/Shell/Makefile b/Source/Applications/Shell/Makefile index f93d80d..0eeb620 100644 --- a/Source/Applications/Shell/Makefile +++ b/Source/Applications/Shell/Makefile @@ -7,7 +7,8 @@ LD = ld LDFLAGS = -T ../../Library/Link.ld Objects = main.o \ - Shell.ns.o + Shell.ns.o \ + Shell-fs.ns.o OutFile = Shell all: $(OutFile) diff --git a/Source/Applications/Shell/Shell-fs.ns.cpp b/Source/Applications/Shell/Shell-fs.ns.cpp new file mode 100644 index 0000000..33bc94e --- /dev/null +++ b/Source/Applications/Shell/Shell-fs.ns.cpp @@ -0,0 +1,52 @@ +#include "Shell.ns.h" + +namespace Shell { + +void ls(Vector& args) { + FSNode d = cwd; + if (args.size() == 2) { + FSNode n = cwd.findFrom(args[1]); + d = FSNode(0); + if (!n.valid()) + outvt << "No such directory : " << args[1] << "\n"; + else if (n.type() != NT_DIRECTORY) + outvt << "Not a directory : " << args[1] << "\n"; + else + d = n; + } + if (d.valid()) outvt << "Contents of directory " << d.path() << " :\n"; + for (u32int i = 0; i < d.getLength(); i++) { + FSNode n = d.getChild(i); + if (n.type() == NT_FILE) { + outvt << " - FILE\t" << n.getName(); + outvt.setCsrCol(30); + outvt << (s32int)n.getLength() << " bytes.\n"; + } else if (n.type() == NT_DIRECTORY) { + outvt << " - DIR\t" << n.getName() << "/"; + outvt.setCsrCol(30); + outvt << (s32int)n.getLength() << " items.\n"; + } + } +} + +void cd(Vector& args) { + if (args.size() != 2) { + outvt << "Invalid argument count.\n"; + } else { + FSNode ncwd = cwd.findFrom(args[1]); + if (!ncwd.valid()) { + outvt << "No such directory : " << args[1] << "\n"; + } else if (ncwd.type() == NT_DIRECTORY) { + ncwd.setCwd(); + cwd = ncwd; + } else { + outvt << "Not a directory.\n"; + } + } +} + +void pwd(Vector& args) { + outvt << "Current directory : " << cwd.path() << "\n"; +} + +} diff --git a/Source/Applications/Shell/Shell.ns.cpp b/Source/Applications/Shell/Shell.ns.cpp index d34f516..4afc6b7 100644 --- a/Source/Applications/Shell/Shell.ns.cpp +++ b/Source/Applications/Shell/Shell.ns.cpp @@ -3,12 +3,23 @@ namespace Shell { -FSNode node(0); +FSNode cwd(0); + u32int run() { - node = FSNode::getRoot(); + struct { //Command list + String name; + void (*cmd)(Vector&); + } commands[] = { + {"ls", ls}, + {"cd", cd}, + {"pwd", pwd}, + {"", 0} + }; + + cwd = FSNode::getCwd(); while (1) { - outvt << node.getName() << " : "; + outvt << "{" << cwd.getName() << "}: "; String s = invt.readLine(); while (s[0] == WChar(" ") or s[0] == WChar("\t")) { s = s.substr(1, s.size() - 1); @@ -44,6 +55,21 @@ u32int run() { Sys::reboot(); outvt << "Something went wrong.\n"; } else { + u32int i = 0; + bool found = false; + while (!commands[i].name.empty()) { + if (commands[i].name == cmd[0]) { + found = true; + if (commands[i].cmd == 0) { + outvt << "Not implemented yet.\n"; + } else { + commands[i].cmd(cmd); + } + break; + } + i++; + } + if (!found) outvt << "Unknown command : " << cmd[0] << "\n"; } } } diff --git a/Source/Applications/Shell/Shell.ns.h b/Source/Applications/Shell/Shell.ns.h index 3be1e0d..8d7067a 100644 --- a/Source/Applications/Shell/Shell.ns.h +++ b/Source/Applications/Shell/Shell.ns.h @@ -7,4 +7,7 @@ namespace Shell { extern FSNode cwd; + extern void ls(Vector& args); + extern void cd(Vector& args); + extern void pwd(Vector& args); } diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 9ef55e9..d2f8c7b 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -148,6 +148,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { FileSystem* fs = RamFS::mount((u8int*)mods[0].mod_start, 1024 * 1024, NULL); DirectoryNode* cwd; cwd = fs->getRootNode(); + Task::currProcess()->setCwd(cwd); VFS::setRootNode(cwd); OK(kvt); PROCESSING(kvt, "Setting up logs..."); diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 4a65c54..4f332d6 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -5,7 +5,7 @@ CXX = g++ LD = ld LDFLAGS = -T Link.ld -Map Map.txt --oformat=elf32-i386 CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -I . -CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -I ../Library/Interface -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL -g +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -I ../Library/Interface -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL ASM = nasm ASMFLAGS = -f elf diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index 53e5ec1..cd897f2 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -8,8 +8,6 @@ u32int KernelShell::m_instances = 0; -#define COMMAND(name, wat) {(void*)name, (void*)(&KernelShell::wat)}, - u32int shellRun(void* ks) { KernelShell* sh = (KernelShell*)ks; u32int ret = sh->run(); diff --git a/Source/Kernel/SyscallManager/Res.ns.h b/Source/Kernel/SyscallManager/Res.ns.h index e454693..d3a0129 100644 --- a/Source/Kernel/SyscallManager/Res.ns.h +++ b/Source/Kernel/SyscallManager/Res.ns.h @@ -5,9 +5,19 @@ namespace Res { +extern Ressource** ressources; +extern u32int size; + u32int registerRes(Ressource* r); void unregisterRes(u32int id); +template +T* get(u32int id, u32int type) { + if (id > size or ressources[id] == 0) return 0; + if (ressources[id]->resType() != type) return 0; + return (T*)ressources[id]; +} + u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, u32int e); } diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index ce0a1d7..5859f86 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -78,6 +78,7 @@ Process::Process(String binfile, u32int uid) : Ressource(PRIF_OBJTYPE, m_callTab m_retval = 0; m_state = P_STARTING; m_uid = uid; + m_cwd = Task::currProcess()->getCwd(); m_inVT = Task::currProcess()->getInVT(); m_outVT = Task::currProcess()->getOutVT(); m_fileDescriptors = 0; diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index 24df783..d0556e5 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -8,6 +8,7 @@ #include #include #include +class DirectoryNode; #include @@ -42,6 +43,7 @@ class Process : public Ressource { PageDirectory* m_pagedir; u32int m_uid; //User ID VirtualTerminal *m_inVT, *m_outVT; + DirectoryNode *m_cwd; Heap *m_userHeap; @@ -79,6 +81,9 @@ class Process : public Ressource { u32int getPid() { return m_pid; } u32int getPpid() { return m_ppid; } + void setCwd(DirectoryNode *cwd) { m_cwd = cwd; } + DirectoryNode *getCwd() { return m_cwd; } + VirtualTerminal* getInVT(); VirtualTerminal* getOutVT(); void setInVT(VirtualTerminal* vt); diff --git a/Source/Kernel/VFS/DirectoryNode.class.cpp b/Source/Kernel/VFS/DirectoryNode.class.cpp index 0c58ca1..381ff49 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.cpp +++ b/Source/Kernel/VFS/DirectoryNode.class.cpp @@ -1,5 +1,24 @@ #include "DirectoryNode.class.h" +call_t DirectoryNode::m_callTable[] = { + CALL1(FNIF_GETIDXCHILD, &DirectoryNode::getIdxChildSC), + CALL1(FNIF_GETNAMECHILD, &DirectoryNode::getNameChildSC), + CALL0(0, 0) +}; + +u32int DirectoryNode::getIdxChildSC(u32int idx) { + FSNode* n = getChild(idx); + if (n != NULL) return n->resId(); + return (u32int) - 1; +} + +u32int DirectoryNode::getNameChildSC(u32int name) { + String* w = (String*)name; + FSNode* n = getChild(*w); + if (n != NULL) return n->resId(); + return (u32int) - 1; +} + bool DirectoryNode::removable() { if (!m_contentLoaded) if (!loadContent()) diff --git a/Source/Kernel/VFS/DirectoryNode.class.h b/Source/Kernel/VFS/DirectoryNode.class.h index 346c4ab..4d9b211 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.h +++ b/Source/Kernel/VFS/DirectoryNode.class.h @@ -9,10 +9,17 @@ class DirectoryNode : public FSNode { Vector m_children; bool m_contentLoaded; + //Syscalls + static call_t m_callTable[]; + u32int getIdxChildSC(u32int index); + u32int getNameChildSC(u32int name); + public: DirectoryNode(String name, FileSystem* fs, FSNode* parent, u32int permissions = 0777, u32int uid = 0, u32int gid = 0) : - FSNode(name, fs, parent, 0, permissions, uid, gid), m_children(), m_contentLoaded(false) {} + FSNode(name, fs, parent, 0, permissions, uid, gid), m_children(), m_contentLoaded(false) { + addCallTable(m_callTable); + } virtual ~DirectoryNode() { if (m_contentLoaded) { for (u32int i = 0; i < m_children.size(); i++) { diff --git a/Source/Kernel/VFS/FSNode-sc.proto.cpp b/Source/Kernel/VFS/FSNode-sc.proto.cpp index fdea85f..1e0c4c1 100644 --- a/Source/Kernel/VFS/FSNode-sc.proto.cpp +++ b/Source/Kernel/VFS/FSNode-sc.proto.cpp @@ -1,6 +1,8 @@ #include "FSNode.proto.h" #include +#include #include +#include call_t FSNode::m_callTable[] = { CALL0(FNIF_GETNAME, &FSNode::getNameSC), @@ -11,11 +13,21 @@ call_t FSNode::m_callTable[] = { CALL0(FNIF_GETGID, &FSNode::getGid), CALL0(FNIF_GETPERM, &FSNode::getPermissions), CALL0(FNIF_GETPATH, &FSNode::getPathSC), + CALL0(FNIF_SETCWD, &FSNode::setCwdSC), CALL0(0, 0) }; u32int FSNode::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) { if (wat == FNIF_SGETRFN) return VFS::getRootNode()->resId(); + if (wat == FNIF_SGETCWD) return Task::currProcess()->getCwd()->resId(); + if (wat == FNIF_SFIND) { + String* path = (String*)a; + if (b == 0) { + return VFS::find(*path)->resId(); + } else { + return VFS::find(*path, Res::get(b, FNIF_OBJTYPE))->resId(); + } + } return (u32int) - 1; } @@ -42,6 +54,13 @@ u32int FSNode::getPathSC() { return VFS::path(this).serialize(); } +u32int FSNode::setCwdSC() { + if (type() == NT_DIRECTORY) { + Task::currProcess()->setCwd((DirectoryNode*)this); + } + return 0; +} + bool FSNode::readable(User* user) { if (user == 0) user = Usr::user(); if (user->getUid() == m_uid) diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h index 8b6974a..6536e21 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -26,6 +26,7 @@ class FSNode : public Ressource { u32int typeSC(); u32int getParentSC(); u32int getPathSC(); + u32int setCwdSC(); bool accessible(); public: diff --git a/Source/Library/Interface/FSNode.iface.h b/Source/Library/Interface/FSNode.iface.h index fd99bab..cba4621 100644 --- a/Source/Library/Interface/FSNode.iface.h +++ b/Source/Library/Interface/FSNode.iface.h @@ -12,6 +12,8 @@ enum { //S : static, GET : get, R : root, FN : fsnode #define FNIF_SGETRFN 0 +#define FNIF_SGETCWD 1 //Get current working directory +#define FNIF_SFIND 2 //Find a node following a path from a node #define FNIF_GETNAME 0x10 #define FNIF_TYPE 0x11 @@ -21,5 +23,9 @@ enum { #define FNIF_GETGID 0x15 #define FNIF_GETPERM 0x16 #define FNIF_GETPATH 0x17 +#define FNIF_SETCWD 0x18 //Sets node as current working directory + +#define FNIF_GETIDXCHILD 0x20 //Get child node from index +#define FNIF_GETNAMECHILD 0x21 //Get child node from name #endif diff --git a/Source/Library/Userland/Binding/FSNode.class.h b/Source/Library/Userland/Binding/FSNode.class.h index 95802a4..61ac991 100644 --- a/Source/Library/Userland/Binding/FSNode.class.h +++ b/Source/Library/Userland/Binding/FSNode.class.h @@ -4,7 +4,13 @@ class FSNode : public RessourceCaller { public: static FSNode getRoot() { - return FSNode(RessourceCaller::sCall(FNIF_OBJTYPE, FNIF_SGETRFN)); + return FSNode(sCall(FNIF_OBJTYPE, FNIF_SGETRFN)); + } + static FSNode getCwd() { + return FSNode(sCall(FNIF_OBJTYPE, FNIF_SGETCWD)); + } + static FSNode find(String path) { //Finds a node starting from root node + return FSNode(sCall(FNIF_OBJTYPE, FNIF_SFIND, (u32int)&path, 0)); } FSNode(u32int id) : RessourceCaller(id, FNIF_OBJTYPE) {} @@ -32,4 +38,16 @@ class FSNode : public RessourceCaller { String path() { return String::unserialize(doCall(FNIF_GETPATH)); } + void setCwd() { + doCall(FNIF_SETCWD); + } + FSNode getChild(u32int idx) { + return FSNode(doCall(FNIF_GETIDXCHILD, idx)); + } + FSNode getChild(String name) { + return FSNode(doCall(FNIF_GETNAMECHILD, (u32int)&name)); + } + FSNode findFrom(String path) { //Search a filesystem node starting from here + return FSNode(sCall(FNIF_OBJTYPE, FNIF_SFIND, (u32int)&path, resId())); + } }; -- cgit v1.2.3