From f0556ed7f051fb101dc68752526696365bf79a11 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 23 Oct 2009 17:28:25 +0200 Subject: More work on syscalls and shell --- Source/Applications/Shell/Help.txt | 16 +++++++++ Source/Applications/Shell/Makefile | 2 +- Source/Applications/Shell/Shell.ns.cpp | 38 ++++++++++++++++++++ Source/Applications/Shell/Shell.ns.h | 1 + Source/Kernel/Core/Sys.ns.cpp | 17 +++++++-- Source/Kernel/Core/Sys.ns.h | 1 + Source/Kernel/Ressources/Configuration/Users | 4 +-- Source/Kernel/Shell/KernelShell.class.cpp | 4 +-- Source/Kernel/SyscallManager/IDT.ns.cpp | 2 ++ Source/Kernel/SyscallManager/Res.ns.cpp | 4 ++- Source/Kernel/SyscallManager/Ressource.class.cpp | 11 +++++- Source/Kernel/SyscallManager/Ressource.class.h | 10 +++++- Source/Kernel/TaskManager/Process.class.cpp | 24 ++++++++++--- Source/Kernel/TaskManager/Process.class.h | 5 +-- Source/Kernel/TaskManager/Thread.class.cpp | 5 ++- Source/Kernel/TaskManager/Thread.class.h | 1 + Source/Kernel/UserManager/User.class.h | 3 ++ Source/Kernel/UserManager/Usr.ns.h | 3 ++ Source/Kernel/VFS/FSNode-sc.proto.cpp | 40 ++++++++++++++++++++++ Source/Kernel/VFS/FSNode.proto.h | 16 +++++---- Source/Kernel/VTManager/VirtualTerminal.proto.h | 1 + Source/Library/Common/BasicString.class.cpp | 8 +++++ Source/Library/Common/BasicString.class.h | 1 + Source/Library/Common/SimpleList.class.h | 1 + Source/Library/Common/WChar.class.h | 2 +- Source/Library/Interface/FSNode.iface.h | 11 ++++++ Source/Library/Interface/Sys.iface.h | 9 +++++ Source/Library/Makefile | 1 + Source/Library/Userland/Binding/FSNode.class.h | 12 +++++++ Source/Library/Userland/Binding/Sys.ns.cpp | 15 ++++++++ Source/Library/Userland/Binding/Sys.ns.h | 9 +++++ .../Userland/Syscall/RessourceCaller.class.h | 2 +- 32 files changed, 252 insertions(+), 27 deletions(-) create mode 100644 Source/Applications/Shell/Help.txt create mode 100644 Source/Library/Interface/Sys.iface.h create mode 100644 Source/Library/Userland/Binding/Sys.ns.cpp create mode 100644 Source/Library/Userland/Binding/Sys.ns.h (limited to 'Source') diff --git a/Source/Applications/Shell/Help.txt b/Source/Applications/Shell/Help.txt new file mode 100644 index 0000000..c1209cf --- /dev/null +++ b/Source/Applications/Shell/Help.txt @@ -0,0 +1,16 @@ + ** Command list for Melon's shell ** + + Command Description Required groups + - help shows this + - reboot reboots your computer root + - halt shuts down your computer root + - loadkeys loads a new keymap root + - free shows free amount of RAM + - uptime shows computer's uptime + - run runs a binary file + - wf writes text to a file + +The shell also supports basic UNIX-like commands : + ls, cd, cat, pwd, rm, mkdir + +The terminal supports scrolling with shift+{up,pgdown,pgup} diff --git a/Source/Applications/Shell/Makefile b/Source/Applications/Shell/Makefile index b33b067..f93d80d 100644 --- a/Source/Applications/Shell/Makefile +++ b/Source/Applications/Shell/Makefile @@ -16,7 +16,7 @@ all: $(OutFile) rebuild: mrproper all $(OutFile): $(Objects) - echo "* Linking $@.o..." + echo "* Linking $@..." $(LD) $(LDFLAGS) ../../Library/Melon.o $^ -o $@ %.o: %.cpp diff --git a/Source/Applications/Shell/Shell.ns.cpp b/Source/Applications/Shell/Shell.ns.cpp index e2433cb..d34f516 100644 --- a/Source/Applications/Shell/Shell.ns.cpp +++ b/Source/Applications/Shell/Shell.ns.cpp @@ -1,4 +1,5 @@ #include "Shell.ns.h" +#include namespace Shell { @@ -9,7 +10,44 @@ u32int run() { while (1) { outvt << node.getName() << " : "; String s = invt.readLine(); + while (s[0] == WChar(" ") or s[0] == WChar("\t")) { + s = s.substr(1, s.size() - 1); + } + if (s[0] == WChar("#")) continue; + if (s.empty()) continue; + + //Parse string + Vector cmd; + cmd.push(String()); + bool inQuote = false; + for (u32int i = 0; i < s.size(); i++) { + if (s[i] == WChar("'")) { + inQuote = !inQuote; + } else if (s[i] == WChar("\\")) { + i++; + cmd.back() += s[i]; + } else if (s[i] == WChar(" ") and !inQuote) { + cmd.push(String()); + } else { + cmd.back() += s[i]; + } + } + + //Run command + if (cmd[0] == "exit") { + if (cmd.size() == 1) return 0; + return cmd[1].toInt(); + } else if (cmd[0] == "halt") { + Sys::halt(); + outvt << "Something went wrong.\n"; + } else if (cmd[0] == "reboot") { + Sys::reboot(); + outvt << "Something went wrong.\n"; + } else { + } } } } + + diff --git a/Source/Applications/Shell/Shell.ns.h b/Source/Applications/Shell/Shell.ns.h index 7d76b33..3be1e0d 100644 --- a/Source/Applications/Shell/Shell.ns.h +++ b/Source/Applications/Shell/Shell.ns.h @@ -6,4 +6,5 @@ namespace Shell { u32int run(); extern FSNode cwd; + } diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index c99544b..1b52c0f 100644 --- a/Source/Kernel/Core/Sys.ns.cpp +++ b/Source/Kernel/Core/Sys.ns.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #define DEBUGVT(x) SimpleVT *x = new SimpleVT(4, 56, 0, 15); x->map(); x->put('\n'); @@ -122,15 +124,18 @@ void panic_assert(char *file, u32int line, char *desc) { while (1) asm volatile("hlt"); //Enter infinite loop for halt } -void reboot() { +void shutdown_cleanup() { asm volatile("cli"); Log::close(); +} + +void reboot() { + shutdown_cleanup(); outb(0x64, 0xFE); } void halt() { - asm volatile("cli"); - Log::close(); + shutdown_cleanup(); String message("MELON SEZ : KTHXBYE, U CAN NAOW TURNZ OFF UR COMPUTER."); SimpleVT vt(3, message.size() + 16, 7, 6); vt.map(); @@ -138,4 +143,10 @@ void halt() { while (1) asm volatile("cli"); } +u32int scall(u8int wat, u32int a, u32int b, u32int c, u32int d) { + if (wat == SYIF_HALT && ISROOT) halt(); + if (wat == SYIF_REBOOT && ISROOT) reboot(); + return (u32int) - 1; +} + } diff --git a/Source/Kernel/Core/Sys.ns.h b/Source/Kernel/Core/Sys.ns.h index 6779585..1ed446c 100644 --- a/Source/Kernel/Core/Sys.ns.h +++ b/Source/Kernel/Core/Sys.ns.h @@ -32,6 +32,7 @@ namespace Sys { void bochs_output_hex(u32int i); void reboot(); void halt(); + u32int scall(u8int, u32int, u32int, u32int, u32int); //System call handler } #endif diff --git a/Source/Kernel/Ressources/Configuration/Users b/Source/Kernel/Ressources/Configuration/Users index ea4367f..cc98bf5 100644 --- a/Source/Kernel/Ressources/Configuration/Users +++ b/Source/Kernel/Ressources/Configuration/Users @@ -1,4 +1,4 @@ # format is uid:username:maingroup:completename -0:root:0:Chuck Norris -1000:alexis211:1: +0:melon:0::The Melon Operating System +1000:alexis211:1:: diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index 232facf..53e5ec1 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -67,7 +67,7 @@ u32int KernelShell::run() { while (1) { m_vt->setColor(SHELL_LIGHTCOLOR); - *m_vt << VFS::path(m_cwd) << " : "; + *m_vt << VFS::path(m_cwd) << " # "; m_vt->setColor(SHELL_ENTRYCOLOR); Vector tokens = m_vt->readLine().split(" "); m_vt->setColor(SHELL_FGCOLOR); @@ -99,7 +99,7 @@ u32int KernelShell::run() { while (commands[i].name != 0) { if (tokens[0] == (const char*)commands[i].name) { found = true; - if (commands[i].name != 0) { + if (commands[i].cmd != 0) { (this->*(commands[i].cmd))(tokens); //Call command } else { *m_vt << "This command isn't enabled... yet !\n"; diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index f447e6f..042ef92 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -76,6 +76,7 @@ extern "C" void interrupt_handler(registers_t regs) { doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } if (regs.int_no == 64) { + asm volatile("sti"); //Make syscalls preemtible u32int res = (regs.eax >> 8); u8int wat = (regs.eax & 0xFF); if (res == 0xFFFFFF) { @@ -91,6 +92,7 @@ extern "C" void interrupt_handler(registers_t regs) { } //Some syscalls have maybee modified current page directory, set it back to one for current process Task::currProcess()->getPagedir()->switchTo(); + asm volatile("cli"); } if (regs.int_no == 66) { //This syscall signals to kernel that thread ended. Task::currentThreadExits(regs.eax); //DO NOT COUNT ON COMMING BACK FROM HERE diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp index 048d17a..c554166 100644 --- a/Source/Kernel/SyscallManager/Res.ns.cpp +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include namespace Res { @@ -20,6 +21,7 @@ static_call_t staticCalls[] = { {PRIF_OBJTYPE, Process::scall}, {THIF_OBJTYPE, Thread::scall}, {FNIF_OBJTYPE, FSNode::scall}, + {SYIF_IFID, Sys::scall}, {0, 0} }; @@ -67,7 +69,7 @@ u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, if (ressource > size or ressources[ressource] == 0) { return (u32int) - 1; } else { - return ressources[ressource]->doCall(wat, a, b, c, d, e); + return ressources[ressource]->call(wat, a, b, c, d, e); } } } diff --git a/Source/Kernel/SyscallManager/Ressource.class.cpp b/Source/Kernel/SyscallManager/Ressource.class.cpp index f2aaccb..8862bca 100644 --- a/Source/Kernel/SyscallManager/Ressource.class.cpp +++ b/Source/Kernel/SyscallManager/Ressource.class.cpp @@ -1,7 +1,8 @@ #include "Ressource.class.h" #include +#include -Ressource::Ressource(u8int type, call_t* callTable) { +Ressource::Ressource(u8int type, call_t* callTable) : m_lock(MUTEX_FALSE) { m_id = Res::registerRes(this); m_type = type; m_callTables = 0; @@ -39,3 +40,11 @@ u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32in } return (u32int) - 1; } + +u32int Ressource::call(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) { + if (!ISROOT && !accessible()) return (u32int) - 1; + m_lock.waitLock(); + u32int r = doCall(id, a, b, c, d, e); + m_lock.unlock(); + return r; +} diff --git a/Source/Kernel/SyscallManager/Ressource.class.h b/Source/Kernel/SyscallManager/Ressource.class.h index f58276b..2ccdcc1 100644 --- a/Source/Kernel/SyscallManager/Ressource.class.h +++ b/Source/Kernel/SyscallManager/Ressource.class.h @@ -2,6 +2,7 @@ #define DEF_RESSOURCE_CLASS_H #include +#include class Ressource; @@ -37,18 +38,25 @@ class Ressource { Ressource(const Ressource&); Ressource& operator=(const Ressource&); + Mutex m_lock; + u32int m_id; u32int m_type; SimpleList *m_callTables; + u32int doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e); + protected: Ressource(u8int type, call_t* callTable = 0); ~Ressource(); + //This function's role is to tell the Ressource if it is supposed to be accesible from current user or not + virtual bool accessible() = 0; //This function should be overloaded by all derivated classes + void addCallTable(call_t* callTable); public: - u32int doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e); + u32int call(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e); u32int resId() { return m_id; } u32int resType() { return m_type; } }; diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 5b777ed..ce0a1d7 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -32,7 +32,7 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { Process* p = new Process(); p->m_pid = 0; p->m_ppid = 0; - p->m_cmdline = cmdline; + p->m_arguments = cmdline.split(" "); p->m_retval = 0; p->m_state = P_RUNNING; p->m_pagedir = kernelPageDirectory; @@ -71,10 +71,10 @@ Process* Process::run(String filename, FSNode* cwd, u32int uid) { } } -Process::Process(String cmdline, u32int uid) : Ressource(PRIF_OBJTYPE, m_callTable) { +Process::Process(String binfile, u32int uid) : Ressource(PRIF_OBJTYPE, m_callTable), m_arguments() { m_pid = Task::nextPid(); m_ppid = Task::currProcess()->getPid(); - m_cmdline = cmdline; + m_arguments.push(binfile); m_retval = 0; m_state = P_STARTING; m_uid = uid; @@ -177,7 +177,20 @@ u32int Process::allocPageSC(u32int pos) { } u32int Process::getCmdlineSC() { - if (Task::currProcess()->getUid() == m_uid or Usr::uid() == 0) return m_cmdline.serialize(); + if (Usr::uid() == m_uid or ISROOT) { + String cmdline; + for (u32int i = 0; i < m_arguments.size(); i++) { + if (i != 0) cmdline += " "; + if (m_arguments[i].contains(" ")) { + cmdline += "'"; + cmdline += m_arguments[i]; + cmdline += "'"; + } else { + cmdline += m_arguments[i]; + } + } + return cmdline.serialize(); + } return (u32int) - 1; } @@ -188,3 +201,6 @@ u32int Process::freePageSC(u32int pos) { m_pagedir->freeFrame(pos); return 0; } +bool Process::accessible() { + return (m_uid == Usr::uid()); +} diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index d5fe454..24df783 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -36,7 +36,7 @@ class Process : public Ressource { u32int m_pid; //Process IDentifier u32int m_ppid; //Parent PID - String m_cmdline; + Vector m_arguments; s32int m_retval; //Can be either a standard return value or an E_* (see #defines above) u8int m_state; //Is one of P_* defined above PageDirectory* m_pagedir; @@ -54,13 +54,14 @@ class Process : public Ressource { u32int getCmdlineSC(); u32int allocPageSC(u32int); u32int freePageSC(u32int); + bool accessible(); public: static u32int scall(u8int, u32int, u32int, u32int, u32int); static Process* createKernel(String cmdline, VirtualTerminal *vt); //Also creates a Thread for what's curently happening static Process* run(String filename, FSNode* cwd, u32int uid); - Process(String cmdline, u32int uid); + Process(String binfile, u32int uid); ~Process(); Heap& heap() { return *m_userHeap; } diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index a9c53ed..ba3612d 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -239,4 +240,6 @@ u32int Thread::finishSC(u32int errcode) { return 0; } - +bool Thread::accessible() { + return (Usr::uid() == m_process->m_uid); +} diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 35a9fd6..6d37350 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -41,6 +41,7 @@ class Thread : public Ressource { static call_t m_callTable[]; u32int sleepSC(u32int msecs); u32int finishSC(u32int errcode); + bool accessible(); public: static u32int scall(u8int, u32int, u32int, u32int, u32int); diff --git a/Source/Kernel/UserManager/User.class.h b/Source/Kernel/UserManager/User.class.h index 1ad55f4..ae02281 100644 --- a/Source/Kernel/UserManager/User.class.h +++ b/Source/Kernel/UserManager/User.class.h @@ -28,16 +28,19 @@ class User { u32int getUid() { return m_uid; } Group* getGroup() { return m_group; } bool isInGroup(u32int gid) { + if (m_group->getGid() == gid) return true; for (u32int i = 0; i < m_extraGroups.size(); i++) if (m_extraGroups[i]->getGid() == gid) return true; return false; } bool isInGroup(String name) { + if (m_group->getName() == name) return true; for (u32int i = 0; i < m_extraGroups.size(); i++) if (m_extraGroups[i]->getName() == name) return true; return false; } bool isInGroup(Group* g) { + if (g == m_group) return true; for (u32int i = 0; i < m_extraGroups.size(); i++) if (m_extraGroups[i] == g) return true; return false; diff --git a/Source/Kernel/UserManager/Usr.ns.h b/Source/Kernel/UserManager/Usr.ns.h index 36ee2cb..ba41d34 100644 --- a/Source/Kernel/UserManager/Usr.ns.h +++ b/Source/Kernel/UserManager/Usr.ns.h @@ -5,6 +5,9 @@ class Group; class User; +#define INGRP(group) Usr::user()->isInGroup(group) +#define ISROOT Usr::user()->isInGroup("root") + namespace Usr { void load(); //Loads users into memory, from /System/Configuration/{Users,Groups} void save(); //Saves config from mem to filesystem diff --git a/Source/Kernel/VFS/FSNode-sc.proto.cpp b/Source/Kernel/VFS/FSNode-sc.proto.cpp index 9e485e1..fdea85f 100644 --- a/Source/Kernel/VFS/FSNode-sc.proto.cpp +++ b/Source/Kernel/VFS/FSNode-sc.proto.cpp @@ -1,11 +1,16 @@ #include "FSNode.proto.h" #include +#include call_t FSNode::m_callTable[] = { CALL0(FNIF_GETNAME, &FSNode::getNameSC), CALL0(FNIF_TYPE, &FSNode::typeSC), CALL0(FNIF_GETPARENT, &FSNode::getParentSC), CALL0(FNIF_GETLENGTH, &FSNode::getLengthSC), + CALL0(FNIF_GETUID, &FSNode::getUid), + CALL0(FNIF_GETGID, &FSNode::getGid), + CALL0(FNIF_GETPERM, &FSNode::getPermissions), + CALL0(FNIF_GETPATH, &FSNode::getPathSC), CALL0(0, 0) }; @@ -32,3 +37,38 @@ u32int FSNode::getParentSC() { if (m_parent != 0) return m_parent->resId(); return (u32int) - 1; } + +u32int FSNode::getPathSC() { + return VFS::path(this).serialize(); +} + +bool FSNode::readable(User* user) { + if (user == 0) user = Usr::user(); + if (user->getUid() == m_uid) + return ((m_permissions >> 6) & 4) != 0; + if (user->isInGroup(m_gid)) + return ((m_permissions >> 3) & 4) != 0; + return (m_permissions & 4) != 0; +} + +bool FSNode::writable(User* user) { + if (user == 0) user = Usr::user(); + if (user->getUid() == m_uid) + return ((m_permissions >> 6) & 2) != 0; + if (user->isInGroup(m_gid)) + return ((m_permissions >> 3) & 2) != 0; + return (m_permissions & 2) != 0; +} + +bool FSNode::runnable(User* user) { + if (user == 0) user = Usr::user(); + if (user->getUid() == m_uid) + return ((m_permissions >> 6) & 1) != 0; + if (user->isInGroup(m_gid)) + return ((m_permissions >> 3) & 1) != 0; + return (m_permissions & 1) != 0; +} + +bool FSNode::accessible() { + return readable(); +} diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h index b648141..8b6974a 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -3,18 +3,13 @@ #include #include + class FSNode; #include #include #include - -enum { - NT_FILE = 1, - NT_DIRECTORY = 2, - NT_SYMLINK = 3, - NT_MOUNTPOINT = 4 -}; +#include class FSNode : public Ressource { protected: @@ -30,6 +25,8 @@ class FSNode : public Ressource { u32int getLengthSC(); u32int typeSC(); u32int getParentSC(); + u32int getPathSC(); + bool accessible(); public: static u32int scall(u8int, u32int, u32int, u32int, u32int); @@ -52,6 +49,11 @@ class FSNode : public Ressource { FileSystem *getFS() { return m_fs; } FSNode* getParent() { return m_parent; } + //Helper functions + bool readable(User* user = 0); + bool writable(User* user = 0); + bool runnable(User* user = 0); + public: bool setName(String name) { bool b = m_fs->setName(this, name); diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index 936e4d4..90fa88e 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -30,6 +30,7 @@ class VirtualTerminal : public Ressource { u32int setCursorLineSC(u32int); u32int setCursorColSC(u32int); u32int isBoxedSC(); + bool accessible() { return true; } public: static u32int scall(u8int, u32int, u32int, u32int, u32int); diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp index b8f7eea..f3a6164 100644 --- a/Source/Library/Common/BasicString.class.cpp +++ b/Source/Library/Common/BasicString.class.cpp @@ -150,6 +150,14 @@ void BasicString::clear() { m_length = 0; } +template +bool BasicString::contains(const T& chr) const { + for (u32int i = 0; i < m_length; i++) { + if (m_string[i] == chr) return true; + } + return false; +} + template Vector< BasicString > BasicString::split(T sep) const { Vector< BasicString > ret; diff --git a/Source/Library/Common/BasicString.class.h b/Source/Library/Common/BasicString.class.h index 17055e8..21041e8 100644 --- a/Source/Library/Common/BasicString.class.h +++ b/Source/Library/Common/BasicString.class.h @@ -43,6 +43,7 @@ class BasicString { u32int size() const { return m_length; } void clear(); bool empty() const { return m_length == 0; } + bool contains(const T& chr) const; Vector< BasicString > split(T sep) const; BasicString substr(s32int start, u32int size); diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h index 7b731db..8fcd834 100644 --- a/Source/Library/Common/SimpleList.class.h +++ b/Source/Library/Common/SimpleList.class.h @@ -48,6 +48,7 @@ class SimpleList { } SimpleList* removeOnce(const T& value) { + if (this == 0) return 0; if (value == m_value) return delThis(); for (SimpleList *iter = this; iter->next() != 0; iter = iter->next()) { if (iter->next()->v() == value) { diff --git a/Source/Library/Common/WChar.class.h b/Source/Library/Common/WChar.class.h index 3eca3d3..5d6d26b 100644 --- a/Source/Library/Common/WChar.class.h +++ b/Source/Library/Common/WChar.class.h @@ -83,7 +83,7 @@ struct WChar { return v; } - inline operator u32int () { return value; } + inline operator u32int () const { return value; } }; #endif diff --git a/Source/Library/Interface/FSNode.iface.h b/Source/Library/Interface/FSNode.iface.h index 482ebd2..fd99bab 100644 --- a/Source/Library/Interface/FSNode.iface.h +++ b/Source/Library/Interface/FSNode.iface.h @@ -1,6 +1,13 @@ #ifndef DEF_FSNODE_IFACE_H #define DEF_FSNODE_IFACE_H +enum { + NT_FILE = 1, + NT_DIRECTORY = 2, + NT_SYMLINK = 3, + NT_MOUNTPOINT = 4 +}; + #define FNIF_OBJTYPE 0x14 //S : static, GET : get, R : root, FN : fsnode @@ -10,5 +17,9 @@ #define FNIF_TYPE 0x11 #define FNIF_GETPARENT 0x12 #define FNIF_GETLENGTH 0x13 +#define FNIF_GETUID 0x14 +#define FNIF_GETGID 0x15 +#define FNIF_GETPERM 0x16 +#define FNIF_GETPATH 0x17 #endif diff --git a/Source/Library/Interface/Sys.iface.h b/Source/Library/Interface/Sys.iface.h new file mode 100644 index 0000000..c734f52 --- /dev/null +++ b/Source/Library/Interface/Sys.iface.h @@ -0,0 +1,9 @@ +#ifndef SYS_IFACE_H +#define SYS_IFACE_H + +#define SYIF_IFID 0xFF + +#define SYIF_HALT 0x1 +#define SYIF_REBOOT 0x2 + +#endif diff --git a/Source/Library/Makefile b/Source/Library/Makefile index a4b9b6a..7091116 100644 --- a/Source/Library/Makefile +++ b/Source/Library/Makefile @@ -16,6 +16,7 @@ Objects = Common/WChar.class.uo \ Common/Heap.class.uo \ Common/Heap-index.class.uo \ Common/String.class.uo \ + Userland/Binding/Sys.ns.uo \ Userland/Syscall/Syscall.wtf.uo \ Userland/Syscall/RessourceCaller.class.uo \ Userland/Start.uo diff --git a/Source/Library/Userland/Binding/FSNode.class.h b/Source/Library/Userland/Binding/FSNode.class.h index eb25782..95802a4 100644 --- a/Source/Library/Userland/Binding/FSNode.class.h +++ b/Source/Library/Userland/Binding/FSNode.class.h @@ -20,4 +20,16 @@ class FSNode : public RessourceCaller { u64int getLength() { return *((u64int*)doCall(FNIF_GETLENGTH)); } + u32int getUid() { + return doCall(FNIF_GETUID); + } + u32int getGid() { + return doCall(FNIF_GETGID); + } + u32int getPerm() { + return doCall(FNIF_GETPERM); + } + String path() { + return String::unserialize(doCall(FNIF_GETPATH)); + } }; diff --git a/Source/Library/Userland/Binding/Sys.ns.cpp b/Source/Library/Userland/Binding/Sys.ns.cpp new file mode 100644 index 0000000..7083e56 --- /dev/null +++ b/Source/Library/Userland/Binding/Sys.ns.cpp @@ -0,0 +1,15 @@ +#include +#include "Sys.ns.h" +#include + +namespace Sys { + +void halt() { + RessourceCaller::sCall(SYIF_IFID, SYIF_HALT); +} + +void reboot() { + RessourceCaller::sCall(SYIF_IFID, SYIF_REBOOT); +} + +} diff --git a/Source/Library/Userland/Binding/Sys.ns.h b/Source/Library/Userland/Binding/Sys.ns.h new file mode 100644 index 0000000..3a8426b --- /dev/null +++ b/Source/Library/Userland/Binding/Sys.ns.h @@ -0,0 +1,9 @@ +#ifndef DEF_SYS_NS_H +#define DEF_SYS_NS_H + +namespace Sys { + void halt(); + void reboot(); +} + +#endif diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.h b/Source/Library/Userland/Syscall/RessourceCaller.class.h index 85beacf..f26216d 100644 --- a/Source/Library/Userland/Syscall/RessourceCaller.class.h +++ b/Source/Library/Userland/Syscall/RessourceCaller.class.h @@ -23,11 +23,11 @@ class RessourceCaller { RessourceCaller(u32int id, u32int type); //Static call -- a call specific to a class and not an object - static u32int sCall(u32int type, u8int wat, u32int a = 0, u32int b = 0, u32int c = 0, u32int d = 0); u32int doCall(u8int call, u32int a = 0, u32int b = 0, u32int c = 0, u32int d = 0, u32int e = 0); public: + static u32int sCall(u32int type, u8int wat, u32int a = 0, u32int b = 0, u32int c = 0, u32int d = 0); u32int resId() { return m_id; } u32int resType() { return m_type; } bool valid() { return m_type != 0; } -- cgit v1.2.3