summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/Applications/Shell/Help.txt16
-rw-r--r--Source/Applications/Shell/Makefile2
-rw-r--r--Source/Applications/Shell/Shell.ns.cpp38
-rw-r--r--Source/Applications/Shell/Shell.ns.h1
-rw-r--r--Source/Kernel/Core/Sys.ns.cpp17
-rw-r--r--Source/Kernel/Core/Sys.ns.h1
-rw-r--r--Source/Kernel/Ressources/Configuration/Users4
-rw-r--r--Source/Kernel/Shell/KernelShell.class.cpp4
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp2
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.cpp4
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.cpp11
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.h10
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp24
-rw-r--r--Source/Kernel/TaskManager/Process.class.h5
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp5
-rw-r--r--Source/Kernel/TaskManager/Thread.class.h1
-rw-r--r--Source/Kernel/UserManager/User.class.h3
-rw-r--r--Source/Kernel/UserManager/Usr.ns.h3
-rw-r--r--Source/Kernel/VFS/FSNode-sc.proto.cpp40
-rw-r--r--Source/Kernel/VFS/FSNode.proto.h16
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal.proto.h1
-rw-r--r--Source/Library/Common/BasicString.class.cpp8
-rw-r--r--Source/Library/Common/BasicString.class.h1
-rw-r--r--Source/Library/Common/SimpleList.class.h1
-rw-r--r--Source/Library/Common/WChar.class.h2
-rw-r--r--Source/Library/Interface/FSNode.iface.h11
-rw-r--r--Source/Library/Interface/Sys.iface.h9
-rw-r--r--Source/Library/Makefile1
-rw-r--r--Source/Library/Userland/Binding/FSNode.class.h12
-rw-r--r--Source/Library/Userland/Binding/Sys.ns.cpp15
-rw-r--r--Source/Library/Userland/Binding/Sys.ns.h9
-rw-r--r--Source/Library/Userland/Syscall/RessourceCaller.class.h2
32 files changed, 252 insertions, 27 deletions
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 <Binding/Sys.ns.h>
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<String> 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 <Core/Log.ns.h>
#include <VTManager/SimpleVT.class.h>
#include <SyscallManager/IDT.ns.h>
+#include <Sys.iface.h>
+#include <UserManager/Usr.ns.h>
#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<String> 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 <Process.iface.h>
#include <Thread.iface.h>
#include <FSNode.iface.h>
+#include <Sys.iface.h>
#include <TaskManager/Task.ns.h>
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 <SyscallManager/Res.ns.h>
+#include <UserManager/Usr.ns.h>
-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 <SimpleList.class.h>
+#include <Mutex.class.h>
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<call_t*> *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<String> 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 <MemoryManager/PageAlloc.ns.h>
#include <DeviceManager/Time.ns.h>
#include <MemoryManager/GDT.ns.h>
+#include <UserManager/Usr.ns.h>
#include <Thread.iface.h>
@@ -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 <VFS/VFS.ns.h>
+#include <UserManager/Usr.ns.h>
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 <common.h>
#include <String.class.h>
+
class FSNode;
#include <VFS/FileSystem.proto.h>
#include <SyscallManager/Ressource.class.h>
#include <FSNode.iface.h>
-
-enum {
- NT_FILE = 1,
- NT_DIRECTORY = 2,
- NT_SYMLINK = 3,
- NT_MOUNTPOINT = 4
-};
+#include <UserManager/User.class.h>
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
@@ -151,6 +151,14 @@ void BasicString<T>::clear() {
}
template <typename T>
+bool BasicString<T>::contains(const T& chr) const {
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] == chr) return true;
+ }
+ return false;
+}
+
+template <typename T>
Vector< BasicString<T> > BasicString<T>::split(T sep) const {
Vector< BasicString<T> > ret;
ret.push(BasicString<T>());
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<T> > split(T sep) const;
BasicString<T> 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<T>* removeOnce(const T& value) {
+ if (this == 0) return 0;
if (value == m_value) return delThis();
for (SimpleList<T> *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 <Sys.iface.h>
+#include "Sys.ns.h"
+#include <Syscall/RessourceCaller.class.h>
+
+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; }