summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-24 18:24:46 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-24 18:24:46 +0200
commitb639b99b3e8f4cf77560d8d473b13d992ac8eb10 (patch)
tree63ebeec75f4ab71d73d743afca04a98636dee165 /Source
parentf62cfdc8ff6297616d68f6b195db7abc82ab457b (diff)
downloadMelon-b639b99b3e8f4cf77560d8d473b13d992ac8eb10.tar.gz
Melon-b639b99b3e8f4cf77560d8d473b13d992ac8eb10.zip
More work on userland syscalls : Files are implemented.
TextFile now is a common (= kernel and userland) library.
Diffstat (limited to 'Source')
-rw-r--r--Source/Applications/SampleApps/Makefile12
-rw-r--r--Source/Applications/SampleApps/cxxdemo.cpp5
-rw-r--r--Source/Applications/Shell/Help.txt2
-rw-r--r--Source/Applications/Shell/Makefile6
-rw-r--r--Source/Applications/Shell/Shell-fs.ns.cpp35
-rw-r--r--Source/Applications/Shell/Shell.ns.cpp10
-rw-r--r--Source/Applications/Shell/Shell.ns.h2
-rw-r--r--Source/Applications/Shell/main.cpp2
-rw-r--r--Source/Kernel/Core/Log.ns.h2
-rw-r--r--Source/Kernel/Core/Sys.ns.cpp5
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp1
-rw-r--r--Source/Kernel/Makefile4
-rw-r--r--Source/Kernel/Shell/KernelShell-fs.class.cpp3
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.cpp2
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp42
-rw-r--r--Source/Kernel/TaskManager/Process.class.h4
-rw-r--r--Source/Kernel/UserManager/Usr.ns.cpp11
-rw-r--r--Source/Kernel/VFS/FSNode-sc.proto.cpp4
-rw-r--r--Source/Kernel/VFS/File-sc.class.cpp68
-rw-r--r--Source/Kernel/VFS/File.class.cpp29
-rw-r--r--Source/Kernel/VFS/File.class.h39
-rw-r--r--Source/Kernel/VFS/FileNode.class.h2
-rw-r--r--Source/Kernel/VFS/TextFile.class.cpp21
-rw-r--r--Source/Kernel/VFS/VFS.ns.cpp43
-rw-r--r--Source/Kernel/VFS/VFS.ns.h5
-rw-r--r--Source/Kernel/VTManager/FileVT.class.h2
-rw-r--r--Source/Library/Common/TextFile.class.cpp30
-rw-r--r--Source/Library/Common/TextFile.class.h (renamed from Source/Kernel/VFS/TextFile.class.h)10
-rw-r--r--Source/Library/Interface/File.iface.h33
-rw-r--r--Source/Library/Interface/Process.iface.h4
-rw-r--r--Source/Library/Interface/Sys.iface.h3
-rw-r--r--Source/Library/Link.ld1
-rw-r--r--Source/Library/Makefile5
-rw-r--r--Source/Library/Userland/Binding/FSNode.class.h1
-rw-r--r--Source/Library/Userland/Binding/File.class.h68
-rw-r--r--Source/Library/Userland/Binding/Process.class.h7
-rw-r--r--Source/Library/Userland/Binding/Sys.ns.cpp15
-rw-r--r--Source/Library/Userland/Binding/Sys.ns.h26
-rw-r--r--Source/Library/Userland/Start.cpp8
39 files changed, 419 insertions, 153 deletions
diff --git a/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile
index a632f87..05f79b1 100644
--- a/Source/Applications/SampleApps/Makefile
+++ b/Source/Applications/SampleApps/Makefile
@@ -1,13 +1,13 @@
.PHONY: clean, mrproper
ASM = nasm
-ASMFLAGS = -f elf
+ASMFLAGS = -f bin
CXX = g++
-CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND
+CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND
LD = ld
-LDFLAGS = -T ../../Library/Link.ld
+LDFLAGS = -T ../../Library/Link.ld -L ../../Library
Applications = asmdemo cxxdemo
@@ -20,13 +20,11 @@ rebuild: mrproper all
echo "* Compiling $<..."
$(CXX) $(CXXFLAGS) -c $< -o $@.o
echo "* Linking $@.o..."
- $(LD) $(LDFLAGS) ../../Library/Melon.o $@.o -o $@
+ $(LD) $(LDFLAGS) $@.o -o $@
%: %.asm
echo "* Compiling $<..."
- $(ASM) $(ASMFLAGS) -o $@.o $<
- echo "* Linking $@.o..."
- $(LD) $(LDFLAGS) $@.o -o $@
+ $(ASM) $(ASMFLAGS) -o $@ $<
clean:
echo "* Removing object files..."
diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp
index b9439ce..3d452e7 100644
--- a/Source/Applications/SampleApps/cxxdemo.cpp
+++ b/Source/Applications/SampleApps/cxxdemo.cpp
@@ -1,9 +1,10 @@
#include <Syscall/Syscall.wtf.h>
-#include <WChar.class.h>
+#include <String.class.h>
#include <Binding/VirtualTerminal.class.h>
#include <Binding/Thread.class.h>
+#include <Binding/File.class.h>
-int main() {
+int main(const Vector<String>& args) {
outvt << "Enter some text plz : ";
String s = invt.readLine();
outvt << s;
diff --git a/Source/Applications/Shell/Help.txt b/Source/Applications/Shell/Help.txt
index c1209cf..0b42361 100644
--- a/Source/Applications/Shell/Help.txt
+++ b/Source/Applications/Shell/Help.txt
@@ -4,7 +4,7 @@
- help shows this
- reboot reboots your computer root
- halt shuts down your computer root
- - loadkeys loads a new keymap root
+ - loadkeys loads a keymap root
- free shows free amount of RAM
- uptime shows computer's uptime
- run runs a binary file
diff --git a/Source/Applications/Shell/Makefile b/Source/Applications/Shell/Makefile
index 0eeb620..bf81af6 100644
--- a/Source/Applications/Shell/Makefile
+++ b/Source/Applications/Shell/Makefile
@@ -1,10 +1,10 @@
.PHONY: clean, mrproper
CXX = g++
-CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND
+CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND
LD = ld
-LDFLAGS = -T ../../Library/Link.ld
+LDFLAGS = -T ../../Library/Link.ld -L ../../Library
Objects = main.o \
Shell.ns.o \
@@ -18,7 +18,7 @@ rebuild: mrproper all
$(OutFile): $(Objects)
echo "* Linking $@..."
- $(LD) $(LDFLAGS) ../../Library/Melon.o $^ -o $@
+ $(LD) $(LDFLAGS) $^ -o $@
%.o: %.cpp
echo "* Compiling $<..."
diff --git a/Source/Applications/Shell/Shell-fs.ns.cpp b/Source/Applications/Shell/Shell-fs.ns.cpp
index b7e585a..1d52836 100644
--- a/Source/Applications/Shell/Shell-fs.ns.cpp
+++ b/Source/Applications/Shell/Shell-fs.ns.cpp
@@ -1,4 +1,5 @@
#include "Shell.ns.h"
+#include <TextFile.class.h>
namespace Shell {
@@ -77,4 +78,38 @@ void mkdir(Vector<String>& args) {
}
}
+void cat(Vector<String>& args) {
+ if (args.size() == 1) outvt << "Meow.\n";
+ for (u32int i = 1; i < args.size(); i++) {
+ TextFile f(args[i], FM_READ, cwd);
+ if (f.valid() && f.validOpened()) {
+ while (!f.eof()) {
+ outvt << f.readLine() << "\n";
+ }
+ f.close();
+ } else {
+ outvt << "Error while reading from file " << args[i] << "\n";
+ }
+ }
+}
+
+void wf(Vector<String>& args) {
+ if (args.size() == 1) {
+ outvt << "No file to write !\n";
+ } else {
+ TextFile f(args[1], FM_TRUNCATE, cwd);
+ if (f.valid() && f.validOpened()) {
+ outvt << "Enter contents for file " << args[1] << " and end your entry with <CR>.<CR>\n";
+ String t = invt.readLine();
+ while (t != ".") {
+ f.write(t, true);
+ t = invt.readLine();
+ }
+ f.close();
+ } else {
+ outvt << "Error opening file.\n";
+ }
+ }
+}
+
}
diff --git a/Source/Applications/Shell/Shell.ns.cpp b/Source/Applications/Shell/Shell.ns.cpp
index fe8c5f9..7213094 100644
--- a/Source/Applications/Shell/Shell.ns.cpp
+++ b/Source/Applications/Shell/Shell.ns.cpp
@@ -16,6 +16,8 @@ u32int run() {
{"pwd", pwd},
{"rm", rm},
{"mkdir", mkdir},
+ {"cat", cat},
+ {"wf", wf},
{"", 0}
};
@@ -56,6 +58,14 @@ u32int run() {
} else if (cmd[0] == "reboot") {
Sys::reboot();
outvt << "Something went wrong.\n";
+ } else if (cmd[0] == "uptime") {
+ outvt << "Uptime : " << (s64int)Sys::uptime() << "s\n";
+ } else if (cmd[0] == "free") {
+ outvt << "Free RAM : " << (s64int)Sys::freeRam() << " Kio of " << (s64int)Sys::totalRam() << " Kio\n";
+ } else if (cmd[0] == "help") {
+ while (cmd.size() > 1) cmd.pop();
+ cmd.push("/Applications/Shell/Help.txt");
+ cat(cmd);
} else {
u32int i = 0;
bool found = false;
diff --git a/Source/Applications/Shell/Shell.ns.h b/Source/Applications/Shell/Shell.ns.h
index 56fdb46..a22c18d 100644
--- a/Source/Applications/Shell/Shell.ns.h
+++ b/Source/Applications/Shell/Shell.ns.h
@@ -12,4 +12,6 @@ namespace Shell {
extern void pwd(Vector<String>& args);
extern void rm(Vector<String>& args);
extern void mkdir(Vector<String>& args);
+ extern void cat(Vector<String>& args);
+ extern void wf(Vector<String>& args);
}
diff --git a/Source/Applications/Shell/main.cpp b/Source/Applications/Shell/main.cpp
index 70da17b..66c4269 100644
--- a/Source/Applications/Shell/main.cpp
+++ b/Source/Applications/Shell/main.cpp
@@ -1,5 +1,5 @@
#include "Shell.ns.h"
-int main() {
+int main(const Vector<String>& args) {
return Shell::run();
}
diff --git a/Source/Kernel/Core/Log.ns.h b/Source/Kernel/Core/Log.ns.h
index d825f62..dc126dc 100644
--- a/Source/Kernel/Core/Log.ns.h
+++ b/Source/Kernel/Core/Log.ns.h
@@ -1,7 +1,7 @@
#ifndef DEF_LOG_NS_H
#define DEF_LOG_NS_H
-#include <VFS/TextFile.class.h>
+#include <TextFile.class.h>
#define KL_PANIC 0
#define KL_CRITICAL 1
diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp
index 1b52c0f..e5dbdc0 100644
--- a/Source/Kernel/Core/Sys.ns.cpp
+++ b/Source/Kernel/Core/Sys.ns.cpp
@@ -5,6 +5,8 @@
#include <SyscallManager/IDT.ns.h>
#include <Sys.iface.h>
#include <UserManager/Usr.ns.h>
+#include <MemoryManager/PhysMem.ns.h>
+#include <DeviceManager/Time.ns.h>
#define DEBUGVT(x) SimpleVT *x = new SimpleVT(4, 56, 0, 15); x->map(); x->put('\n');
@@ -146,6 +148,9 @@ void halt() {
u32int scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
if (wat == SYIF_HALT && ISROOT) halt();
if (wat == SYIF_REBOOT && ISROOT) reboot();
+ if (wat == SYIF_UPTIME) return Time::uptime();
+ if (wat == SYIF_TOTALRAM) return PhysMem::total() * 4;
+ if (wat == SYIF_FREERAM) return PhysMem::free() * 4;
return (u32int) - 1;
}
diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp
index d2f8c7b..76d8971 100644
--- a/Source/Kernel/Core/kmain.wtf.cpp
+++ b/Source/Kernel/Core/kmain.wtf.cpp
@@ -26,7 +26,6 @@
#include <VFS/FileNode.class.h>
#include <VFS/VFS.ns.h>
#include <VFS/DirectoryNode.class.h>
-#include <VFS/TextFile.class.h>
#include <Core/Log.ns.h>
#include <Shell/KernelShell.class.h>
diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile
index 4f332d6..301d64c 100644
--- a/Source/Kernel/Makefile
+++ b/Source/Kernel/Makefile
@@ -52,12 +52,13 @@ Objects = Core/loader.wtf.o \
../Library/Common/Heap.class.o \
../Library/Common/Heap-index.class.o \
../Library/Common/Mutex.class.o \
+ ../Library/Common/TextFile.class.o \
VFS/Partition.class.o \
VFS/Part.ns.o \
VFS/VFS.ns.o \
VFS/FSNode-sc.proto.o \
VFS/File.class.o \
- VFS/TextFile.class.o \
+ VFS/File-sc.class.o \
VFS/DirectoryNode.class.o \
UserManager/Usr.ns.o \
FileSystems/RamFS/RamFS.class.o \
@@ -94,6 +95,7 @@ $(OutFile): $(Objects)
clean:
echo "* Removing object files..."
+ rm -rf $(Objects)
rm -rf *.o
rm -rf */*.o
rm -rf */*/*.o
diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp
index f013f1b..bc7e137 100644
--- a/Source/Kernel/Shell/KernelShell-fs.class.cpp
+++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp
@@ -115,6 +115,9 @@ void KernelShell::run(Vector<String>& args) {
} else {
p->setInVT(m_vt);
p->setOutVT(m_vt);
+ for (u32int i = 2; i < args.size(); i++) {
+ p->pushArg(args[i]);
+ }
p->start();
while (p->getState() != P_FINISHED) Task::currThread()->sleep(10);
delete p;
diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp
index c554166..128f315 100644
--- a/Source/Kernel/SyscallManager/Res.ns.cpp
+++ b/Source/Kernel/SyscallManager/Res.ns.cpp
@@ -6,6 +6,7 @@
#include <FSNode.iface.h>
#include <Sys.iface.h>
#include <TaskManager/Task.ns.h>
+#include <VFS/File.class.h>
namespace Res {
@@ -21,6 +22,7 @@ static_call_t staticCalls[] = {
{PRIF_OBJTYPE, Process::scall},
{THIF_OBJTYPE, Thread::scall},
{FNIF_OBJTYPE, FSNode::scall},
+ {FLIF_OBJTYPE, File::scall},
{SYIF_IFID, Sys::scall},
{0, 0}
};
diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp
index 5859f86..a7e7d7c 100644
--- a/Source/Kernel/TaskManager/Process.class.cpp
+++ b/Source/Kernel/TaskManager/Process.class.cpp
@@ -6,6 +6,8 @@
#include <Process.iface.h>
#include <UserManager/Usr.ns.h>
+#define ISPARENT Task::currProcess()->getPid() == m_ppid
+
namespace Mem {
extern Heap kheap;
}
@@ -16,7 +18,8 @@ call_t Process::m_callTable[] = {
CALL1(PRIF_FREEPAGE, &Process::freePageSC),
CALL0(PRIF_GETPID, &Process::getPid),
CALL0(PRIF_GETPPID, &Process::getPpid),
- CALL0(PRIF_GETCMDLINE, &Process::getCmdlineSC),
+ CALL0(PRIF_ARGC, &Process::argcSC),
+ CALL1(PRIF_ARGV, &Process::argvSC),
CALL0(0, 0)
};
@@ -100,16 +103,20 @@ void Process::start() {
if (m_state == P_STARTING) m_state = P_RUNNING;
}
+void Process::pushArg(const String& arg) {
+ m_arguments.push(arg);
+}
+
void Process::exit() {
for (u32int i = 0; i < m_threads.size(); i++) {
delete m_threads[i];
}
m_threads.clear();
- for (SimpleList<File*> *iter = m_fileDescriptors; iter != 0; iter = iter->next()) {
- iter->v()->close(false);
- delete iter->v();
+ while (m_fileDescriptors != 0) {
+ m_fileDescriptors->v()->close(false);
+ delete m_fileDescriptors->v();
+ m_fileDescriptors = m_fileDescriptors->delThis();
}
- if (m_fileDescriptors != 0) delete m_fileDescriptors; //Will recursively delete whole list
m_state = P_FINISHED;
}
@@ -177,20 +184,17 @@ u32int Process::allocPageSC(u32int pos) {
return 0;
}
-u32int Process::getCmdlineSC() {
- 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();
+u32int Process::argcSC() {
+ if (Usr::uid() == m_uid or ISROOT or ISPARENT) {
+ return (m_arguments.size());
+ }
+ return (u32int) - 1;
+}
+
+u32int Process::argvSC(u32int idx) {
+ if (idx >= m_arguments.size()) return (u32int) - 1;
+ if (Usr::uid() == m_uid or ISROOT or ISPARENT) {
+ return m_arguments[idx].serialize();
}
return (u32int) - 1;
}
diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h
index d0556e5..ec5a90d 100644
--- a/Source/Kernel/TaskManager/Process.class.h
+++ b/Source/Kernel/TaskManager/Process.class.h
@@ -53,7 +53,8 @@ class Process : public Ressource {
//System calls
static call_t m_callTable[];
u32int exitSC();
- u32int getCmdlineSC();
+ u32int argcSC();
+ u32int argvSC(u32int);
u32int allocPageSC(u32int);
u32int freePageSC(u32int);
bool accessible();
@@ -69,6 +70,7 @@ class Process : public Ressource {
Heap& heap() { return *m_userHeap; }
void start(); //Starts thread execution - sets m_state to P_RUNNING if == P_STARTING
+ void pushArg(const String& arg);
void exit(); //Exits properly process by killing all threads and deleting file descriptors
void registerThread(Thread* t); //Called when a thread starts
void threadFinishes(Thread* thread, u32int retval); //Called when a thread finishes
diff --git a/Source/Kernel/UserManager/Usr.ns.cpp b/Source/Kernel/UserManager/Usr.ns.cpp
index a551344..db371ae 100644
--- a/Source/Kernel/UserManager/Usr.ns.cpp
+++ b/Source/Kernel/UserManager/Usr.ns.cpp
@@ -1,9 +1,10 @@
#include "Usr.ns.h"
+#include <Core/Log.ns.h>
#include <UserManager/User.class.h>
#include <SimpleList.class.h>
#include <TaskManager/Task.ns.h>
-#include <VFS/TextFile.class.h>
+#include <TextFile.class.h>
/*
* Syntax for Users and Groups configuration files : one entry per line
@@ -29,6 +30,10 @@ void load() {
m_groups = m_groups->cons(Group(data[1], data[0].toInt()));
}
}
+ if (m_groups == 0) {
+ m_groups = m_groups->cons(Group("root", 0)); //In case, add a default group
+ Log::log(KL_WARNING, "Usr.ns : group file invalid, had to add default group.");
+ }
TextFile users("/System/Configuration/Users", FM_READ);
while (!users.eof()) {
@@ -38,6 +43,10 @@ void load() {
m_users = m_users->cons(User(data[1], data[4], group(data[2].toInt()), data[3], data[0].toInt()));
}
}
+ if (m_users == 0) {
+ m_users = m_users->cons(User("melon", "MelOS", group(0), "", 0));
+ Log::log(KL_WARNING, "Usr.ns : users file invalid, had to add default users.");
+ }
}
void save() {
diff --git a/Source/Kernel/VFS/FSNode-sc.proto.cpp b/Source/Kernel/VFS/FSNode-sc.proto.cpp
index 279303b..717ccef 100644
--- a/Source/Kernel/VFS/FSNode-sc.proto.cpp
+++ b/Source/Kernel/VFS/FSNode-sc.proto.cpp
@@ -35,9 +35,9 @@ u32int FSNode::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
String* path = (String*)a;
FSNode* n;
if (b == 0) {
- n = VFS::mkdir(*path);
+ n = VFS::createDirectory(*path, 0, true);
} else {
- n = VFS::mkdir(*path, Res::get<DirectoryNode>(b, FNIF_OBJTYPE));
+ n = VFS::createDirectory(*path, Res::get<DirectoryNode>(b, FNIF_OBJTYPE), true);
}
if (n != 0) return n->resId();
}
diff --git a/Source/Kernel/VFS/File-sc.class.cpp b/Source/Kernel/VFS/File-sc.class.cpp
new file mode 100644
index 0000000..e5e8e25
--- /dev/null
+++ b/Source/Kernel/VFS/File-sc.class.cpp
@@ -0,0 +1,68 @@
+#include "File.class.h"
+#include <VFS/VFS.ns.h>
+#include <TaskManager/Task.ns.h>
+#include <FSNode.iface.h>
+#include <SyscallManager/Res.ns.h>
+
+u32int File::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
+ if (wat == FLIF_SOPEN) {
+ String* name = (String*)a;
+ FSNode* start = Res::get<FSNode>(c, FNIF_OBJTYPE);
+ File* f = new File();
+ if (!f->open(*name, b, start, true)) {
+ delete f;
+ } else {
+ return f->resId();
+ }
+ }
+ return (u32int) - 1;
+}
+
+u32int File::closeSC() {
+ if (!valid()) return 1;
+ close();
+ return 0;
+}
+
+u32int File::validSC() {
+ return (valid() ? 1 : 0);
+}
+
+u32int File::readSC(u32int max_length, u32int ptr) {
+ if (!m_file->readable()) return 0;
+ return read(max_length, (u8int*)ptr);
+}
+
+u32int File::writeSC(u32int length, u32int ptr) {
+ if (!m_file->writable()) return 0;
+ return (write(length, (u8int*)ptr) ? 1 : 0);
+}
+
+u32int File::seekSC(u32int counta, u32int countb, u32int mode) {
+ union {
+ u32int a[2];
+ u64int x;
+ } wat = {{counta, countb}};
+ return (seek(wat.x, mode) ? 1 : 0);
+}
+
+u32int File::positionSC() {
+ u64int* w = (u64int*)Mem::mkXchgSpace(sizeof(u64int));
+ *w = position();
+ return (u32int)w;
+}
+
+u32int File::lengthSC() {
+ u64int* w = (u64int*)Mem::mkXchgSpace(sizeof(u64int));
+ *w = length();
+ return (u32int)w;
+}
+
+u32int File::eofSC() {
+ return (eof() ? 1 : 0);
+}
+
+bool File::accessible() {
+ if (ISROOT or Usr::uid() == m_process->getUid()) return true;
+ return false;
+}
diff --git a/Source/Kernel/VFS/File.class.cpp b/Source/Kernel/VFS/File.class.cpp
index fbaabbe..c5ddcd6 100644
--- a/Source/Kernel/VFS/File.class.cpp
+++ b/Source/Kernel/VFS/File.class.cpp
@@ -2,11 +2,23 @@
#include <VFS/VFS.ns.h>
#include <TaskManager/Task.ns.h>
-File::File() : m_file(NULL), m_valid(false), m_writable(false), m_position(0) {
+call_t File::m_callTable[] = {
+ CALL0(FLIF_CLOSE, &File::closeSC),
+ CALL0(FLIF_VALID, &File::validSC),
+ CALL2(FLIF_READ, &File::readSC),
+ CALL2(FLIF_WRITE, &File::writeSC),
+ CALL3(FLIF_SEEK, &File::seekSC),
+ CALL0(FLIF_POSITION, &File::positionSC),
+ CALL0(FLIF_LENGTH, &File::lengthSC),
+ CALL0(FLIF_EOF, &File::eofSC),
+ CALL0(0, 0)
+};
+
+File::File() : Ressource(FLIF_OBJTYPE, m_callTable), m_file(NULL), m_valid(false), m_writable(false), m_position(0) {
}
File::File(String filename, u8int mode, FSNode* start) :
- m_file(NULL), m_valid(false), m_writable(false), m_position(0) {
+ Ressource(FLIF_OBJTYPE, m_callTable), m_file(NULL), m_valid(false), m_writable(false), m_position(0) {
open(filename, mode, start);
}
@@ -14,13 +26,13 @@ File::~File() {
close();
}
-bool File::open(String filename, u8int mode, FSNode* start) {
+bool File::open(String filename, u8int mode, FSNode* start, bool vrfyperm) {
if (m_valid) return false;
FSNode* node = VFS::find(filename, start);
if (node == NULL){
if (mode == FM_READ) return false;
- node = VFS::createFile(filename, start);
+ node = VFS::createFile(filename, start, vrfyperm);
if (node == 0) return false;
}
if (node->type() != NT_FILE) return false;
@@ -28,7 +40,9 @@ bool File::open(String filename, u8int mode, FSNode* start) {
m_file = (FileNode*) node;
m_writable = (mode != FM_READ);
- if (!m_file->writable() and m_writable) return false;
+ if (vrfyperm and m_writable and !m_file->writable()) return false;
+ if (vrfyperm and !m_file->readable()) return false;
+ if (!m_file->fsWritable() and m_writable) return false;
if (mode == FM_READ or mode == FM_REPLACE) {
m_position = 0;
@@ -44,7 +58,8 @@ bool File::open(String filename, u8int mode, FSNode* start) {
else
m_file->m_writers++;
- Task::currProcess()->registerFileDescriptor(this);
+ m_process = Task::currProcess();
+ m_process->registerFileDescriptor(this);
m_valid = true;
return true;
}
@@ -135,5 +150,5 @@ void File::close(bool unregisterFD) {
m_file = NULL;
m_position = 0;
m_writable = false;
- if (unregisterFD) Task::currProcess()->unregisterFileDescriptor(this);
+ if (unregisterFD) m_process->unregisterFileDescriptor(this);
}
diff --git a/Source/Kernel/VFS/File.class.h b/Source/Kernel/VFS/File.class.h
index f5d0c56..00b92b6 100644
--- a/Source/Kernel/VFS/File.class.h
+++ b/Source/Kernel/VFS/File.class.h
@@ -3,35 +3,40 @@
#include <VFS/FileNode.class.h>
#include <ByteArray.class.h>
+#include <File.iface.h>
+#include <SyscallManager/Ressource.class.h>
+class Process;
-enum {
- FM_READ = 0, //Open for read, put cursor at beginning
- FM_TRUNCATE = 1, //Open for write, truncating file before
- FM_APPEND = 2, //Open for write, put cursor at end
- FM_REPLACE = 3 //Open for write, put cursor at beginning
-};
-
-enum {
- SM_FORWARD = 0, //Seek from actual position
- SM_BACKWARD = 1, //Seek from actual position, backward
- SM_BEGINNING = 2, //Seek from start of file
- SM_END = 3, //Seek from end of file
-};
-
-class File {
+class File : public Ressource {
protected:
FileNode* m_file;
bool m_valid; //Is a file opened and valid ?
bool m_writable; //Is file opened for write ?
u64int m_position;
+ Process* m_process;
+
+ //Syscalls
+ static call_t m_callTable[];
+ u32int closeSC();
+ u32int validSC();
+ u32int readSC(u32int, u32int);
+ u32int writeSC(u32int, u32int);
+ u32int seekSC(u32int, u32int, u32int);
+ u32int positionSC();
+ u32int lengthSC();
+ u32int eofSC();
+ bool accessible();
public:
+ static u32int scall(u8int, u32int, u32int, u32int, u32int);
+
File();
File(String filename, u8int mode = FM_READ, FSNode* start = 0);
virtual ~File();
- bool open(String filename, u8int mode = FM_READ, FSNode* start = 0);
+ bool open(String filename, u8int mode = FM_READ, FSNode* start = 0, bool vrfyperm = false);
void close(bool unregisterFD = true); //unregisterFD = whether or not we must unregister the file descriptor from process
+ bool valid() { return m_valid; }
u32int read(u32int max_length, u8int *data);
bool write(u32int length, u8int *data);
@@ -49,8 +54,6 @@ class File {
u64int position() { return m_position; }
u64int length() { return m_file->getLength(); }
bool eof();
-
- bool valid() { return m_valid; }
};
#endif
diff --git a/Source/Kernel/VFS/FileNode.class.h b/Source/Kernel/VFS/FileNode.class.h
index 7ab617f..e99ef5e 100644
--- a/Source/Kernel/VFS/FileNode.class.h
+++ b/Source/Kernel/VFS/FileNode.class.h
@@ -19,7 +19,7 @@ class FileNode : public FSNode {
u8int type() { return NT_FILE; }
bool removable() { return true; }
bool used() { return (m_readers != 0 or m_writers != 0); }
- bool writable() { return m_fs->isWritable(); }
+ bool fsWritable() { return m_fs->isWritable(); }
u32int read(u64int position, u32int max_length, u8int *data) {
return m_fs->read(this, position, max_length, data);
diff --git a/Source/Kernel/VFS/TextFile.class.cpp b/Source/Kernel/VFS/TextFile.class.cpp
deleted file mode 100644
index a877392..0000000
--- a/Source/Kernel/VFS/TextFile.class.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "TextFile.class.h"
-
-bool TextFile::write(String str, bool addnl) {
- ByteArray a(str, m_encoding);
- if (addnl) a += (u8int)'\n';
- return File::write(a);
-}
-
-String TextFile::readLine(char separator) {
- ByteArray buffer;
- while (1) {
- char c;
- if (read(1, (u8int*)&c) == 0) {
- return buffer.toString(m_encoding);
- }
- if (c == separator) {
- return buffer.toString(m_encoding);
- }
- buffer += (u8int)c;
- }
-}
diff --git a/Source/Kernel/VFS/VFS.ns.cpp b/Source/Kernel/VFS/VFS.ns.cpp
index fdfc265..e95b911 100644
--- a/Source/Kernel/VFS/VFS.ns.cpp
+++ b/Source/Kernel/VFS/VFS.ns.cpp
@@ -39,7 +39,7 @@ FSNode* find(const String& path, FSNode* start) {
return node;
}
-FSNode* createFile(const String& path, FSNode* start) {
+FSNode* createFile(const String& path, FSNode* start, bool vrfyperm) {
if (find(path, start) != NULL) return NULL; //Something already has that name.
if (start == 0) start = rootNode;
@@ -65,13 +65,12 @@ FSNode* createFile(const String& path, FSNode* start) {
}
if (node->type() == NT_DIRECTORY) {
- return ((DirectoryNode*)node)->createFile(name);
- } else {
- return NULL;
+ if ((vrfyperm && node->writable()) or !vrfyperm) return ((DirectoryNode*)node)->createFile(name);
}
+ return NULL;
}
-FSNode* createDirectory(const String& path, FSNode* start) {
+FSNode* createDirectory(const String& path, FSNode* start, bool vrfyperm) {
if (find(path, start) != NULL) return NULL; //Something already has that name.
if (start == 0) start = rootNode;
@@ -97,40 +96,8 @@ FSNode* createDirectory(const String& path, FSNode* start) {
}
if (node->type() == NT_DIRECTORY) {
- return ((DirectoryNode*)node)->createDirectory(name);
- } else {
- return NULL;
+ if ((vrfyperm && node->writable()) or !vrfyperm) return ((DirectoryNode*)node)->createDirectory(name);
}
-}
-
-//Same as createDirectory but checks for parent directory permissions for current process
-FSNode* mkdir(const String& path, FSNode* start) {
- if (find(path, start) != NULL) return NULL; //Something already has that name.
- if (start == 0) start = rootNode;
-
- Vector<String> p = path.split("/");
- String name = p.back();
- p.pop();
-
- FSNode* node = start;
- if (!path.empty()) {
- if (p[0].empty()) node = rootNode;
- for (u32int i = 0; i < p.size(); i++) {
- if (p[i] == "..") {
- node = node->getParent();
- } else if (!p[i].empty() and p[i] != ".") {
- if (node->type() == NT_DIRECTORY) {
- node = ((DirectoryNode*)node)->getChild(p[i]);
- } else {
- node = NULL;
- }
- }
- if (node == NULL) return node;
- }
- }
-
- if (node->type() == NT_DIRECTORY)
- if (node->writable()) return ((DirectoryNode*)node)->createDirectory(name);
return NULL;
}
diff --git a/Source/Kernel/VFS/VFS.ns.h b/Source/Kernel/VFS/VFS.ns.h
index 63229bf..f1d628f 100644
--- a/Source/Kernel/VFS/VFS.ns.h
+++ b/Source/Kernel/VFS/VFS.ns.h
@@ -13,9 +13,8 @@ namespace VFS {
DirectoryNode* getRootNode();
FSNode* find(const String& path, FSNode* start = 0);
- FSNode* createFile(const String& path, FSNode* start = 0);
- FSNode* createDirectory(const String& path, FSNode* start = 0);
- FSNode* mkdir(const String& path, FSNode* start = 0); //Same as createDirectory, except it checks for parent directory writablilty by current process
+ FSNode* createFile(const String& path, FSNode* start = 0, bool vrfyperm = false);
+ FSNode* createDirectory(const String& path, FSNode* start = 0, bool vrfyperm = false);
bool remove(FSNode* node);
bool remove(const String& path, FSNode* start = 0); //Returns false for non-empty directories
String path(FSNode* node); //Returns complete path for a node
diff --git a/Source/Kernel/VTManager/FileVT.class.h b/Source/Kernel/VTManager/FileVT.class.h
index 61f4d6f..ed3e224 100644
--- a/Source/Kernel/VTManager/FileVT.class.h
+++ b/Source/Kernel/VTManager/FileVT.class.h
@@ -1,7 +1,7 @@
#ifndef DEF_FILEVT_CLASS_H
#define DEF_FILEVT_CLASS_H
-#include <VFS/TextFile.class.h>
+#include <TextFile.class.h>
#include <VTManager/VirtualTerminal.proto.h>
class FileVT : public VirtualTerminal {
diff --git a/Source/Library/Common/TextFile.class.cpp b/Source/Library/Common/TextFile.class.cpp
new file mode 100644
index 0000000..040e2d7
--- /dev/null
+++ b/Source/Library/Common/TextFile.class.cpp
@@ -0,0 +1,30 @@
+#include "TextFile.class.h"
+
+bool TextFile::write(String str, bool addnl) {
+ ByteArray a(str, m_encoding);
+ if (addnl) a += (u8int)'\n';
+ return File::write(a);
+}
+
+String TextFile::readLine(char separator) {
+ const u32int bufflen = 512;
+ String ret;
+ ByteArray temp;
+ while (1) {
+ temp.resize(bufflen);
+ u32int r = read(temp);
+ u32int l = r;
+ for (u32int i = 0; i < r; i++) {
+ if (temp[i] == separator) {
+ l = i;
+ temp.resize(i);
+ break;
+ }
+ }
+ ret += temp.toString(m_encoding);
+ if (l != r or r != bufflen) {
+ if (l != r) seek((r - l) - 1, SM_BACKWARD);
+ return ret;
+ }
+ }
+}
diff --git a/Source/Kernel/VFS/TextFile.class.h b/Source/Library/Common/TextFile.class.h
index a0cd505..3749b6a 100644
--- a/Source/Kernel/VFS/TextFile.class.h
+++ b/Source/Library/Common/TextFile.class.h
@@ -1,16 +1,26 @@
#ifndef DEF_TEXTFILE_CLASS_H
#define DEF_TEXTFILE_CLASS_H
+#ifdef THIS_IS_MELON_KERNEL
#include <VFS/File.class.h>
+#else
+#include <Binding/File.class.h>
+#endif
class TextFile : public File {
private:
u8int m_encoding;
public:
+#ifdef THIS_IS_MELON_KERNEL
TextFile(u8int encoding = UE_UTF8) : File() { m_encoding = encoding; }
TextFile(String filename, u8int mode = FM_READ, FSNode* start = 0, u8int encoding = UE_UTF8)
: File(filename, mode, start) { m_encoding = encoding; }
+#else
+ TextFile(u32int id, u8int encoding = UE_UTF8) : File(id) { m_encoding = encoding; }
+ TextFile(String filename, u8int mode = FM_READ, FSNode start = FSNode(0), u8int encoding = UE_UTF8)
+ : File(filename, mode, start) { m_encoding = encoding; }
+#endif
~TextFile() {}
void setEncoding(u8int encoding = UE_UTF8) { m_encoding = encoding; }
diff --git a/Source/Library/Interface/File.iface.h b/Source/Library/Interface/File.iface.h
new file mode 100644
index 0000000..e1030b8
--- /dev/null
+++ b/Source/Library/Interface/File.iface.h
@@ -0,0 +1,33 @@
+#ifndef DEF_FILE_IFACE_H
+#define DEF_FILE_IFACE_H
+
+enum {
+ FM_READ = 0, //Open for read, put cursor at beginning
+ FM_TRUNCATE = 1, //Open for write, truncating file before
+ FM_APPEND = 2, //Open for write, put cursor at end
+ FM_REPLACE = 3 //Open for write, put cursor at beginning
+};
+
+enum {
+ SM_FORWARD = 0, //Seek from actual position
+ SM_BACKWARD = 1, //Seek from actual position, backward
+ SM_BEGINNING = 2, //Seek from start of file
+ SM_END = 3, //Seek from end of file
+};
+
+#define FLIF_OBJTYPE 0x13
+
+#define FLIF_SOPEN 0x01
+
+#define FLIF_CLOSE 0x05
+#define FLIF_VALID 0x06
+
+#define FLIF_READ 0x0A
+#define FLIF_WRITE 0x0B
+
+#define FLIF_SEEK 0x10
+#define FLIF_POSITION 0x11
+#define FLIF_LENGTH 0x12
+#define FLIF_EOF 0x13
+
+#endif
diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h
index b79639d..52543aa 100644
--- a/Source/Library/Interface/Process.iface.h
+++ b/Source/Library/Interface/Process.iface.h
@@ -11,6 +11,8 @@
#define PRIF_FREEPAGE 0x03
#define PRIF_GETPID 0x04
#define PRIF_GETPPID 0x05
-#define PRIF_GETCMDLINE 0x06
+
+#define PRIF_ARGC 0x10
+#define PRIF_ARGV 0x11
#endif
diff --git a/Source/Library/Interface/Sys.iface.h b/Source/Library/Interface/Sys.iface.h
index c734f52..bebab41 100644
--- a/Source/Library/Interface/Sys.iface.h
+++ b/Source/Library/Interface/Sys.iface.h
@@ -5,5 +5,8 @@
#define SYIF_HALT 0x1
#define SYIF_REBOOT 0x2
+#define SYIF_UPTIME 0x3
+#define SYIF_TOTALRAM 0x4
+#define SYIF_FREERAM 0x5
#endif
diff --git a/Source/Library/Link.ld b/Source/Library/Link.ld
index f06f568..68591fd 100644
--- a/Source/Library/Link.ld
+++ b/Source/Library/Link.ld
@@ -1,4 +1,5 @@
ENTRY (start)
+INPUT (Melon.o)
SECTIONS{
. = 0x10000000;
diff --git a/Source/Library/Makefile b/Source/Library/Makefile
index 7091116..5a7a039 100644
--- a/Source/Library/Makefile
+++ b/Source/Library/Makefile
@@ -1,7 +1,7 @@
.PHONY: clean, mrproper
CXX = g++
-CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I Common -I Userland -I Interface -D THIS_IS_MELON_USERLAND
+CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I Common -I Userland -I Interface -D THIS_IS_MELON_USERLAND
ASM = nasm
ASMFLAGS = -f elf
@@ -16,7 +16,8 @@ Objects = Common/WChar.class.uo \
Common/Heap.class.uo \
Common/Heap-index.class.uo \
Common/String.class.uo \
- Userland/Binding/Sys.ns.uo \
+ Common/TextFile.class.uo \
+ Common/ByteArray.class.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 6a860ea..a7adbc0 100644
--- a/Source/Library/Userland/Binding/FSNode.class.h
+++ b/Source/Library/Userland/Binding/FSNode.class.h
@@ -2,6 +2,7 @@
#define DEF_FSNODE_CLASS_H
#include <Syscall/RessourceCaller.class.h>
+#include <String.class.h>
#include <FSNode.iface.h>
class FSNode : public RessourceCaller {
diff --git a/Source/Library/Userland/Binding/File.class.h b/Source/Library/Userland/Binding/File.class.h
new file mode 100644
index 0000000..4d1ac16
--- /dev/null
+++ b/Source/Library/Userland/Binding/File.class.h
@@ -0,0 +1,68 @@
+#ifndef DEF_FILE_CLASS_H
+#define DEF_FILE_CLASS_H
+
+#include <File.iface.h>
+#include <Binding/FSNode.class.h>
+#include <Syscall/RessourceCaller.class.h>
+#include <Binding/VirtualTerminal.class.h>
+#include <ByteArray.class.h>
+
+class File : public RessourceCaller {
+ public:
+ File(String name, u8int mode, FSNode start = FSNode(0)) :
+ RessourceCaller(sCall(FLIF_OBJTYPE, FLIF_SOPEN, (u32int)&name, mode, start.resId()), FLIF_OBJTYPE) {
+ }
+ File(u32int id) : RessourceCaller(id, FLIF_OBJTYPE) {}
+
+ void close() {
+ doCall(FLIF_CLOSE);
+ }
+ bool validOpened() {
+ return (doCall(FLIF_VALID) != 0);
+ }
+ u32int read(u32int max_length, u8int *ptr) {
+ return (doCall(FLIF_READ, max_length, (u32int)ptr));
+ }
+ bool write(u32int length, u8int* ptr) {
+ return (doCall(FLIF_WRITE, length, (u32int)ptr) != 0);
+ }
+ u32int read(ByteArray &data) {
+ if (!valid()) {
+ data.clear();
+ return 0;
+ }
+ u32int l = read(data.size(), (u8int*)data);
+ if (l != data.size()) data.resize(l);
+ return l;
+ }
+ bool write(ByteArray &data) {
+ if (!valid()) return false;
+ return write(data.size(), (u8int*)data);
+ }
+
+ template <typename T> bool read(T* elem) {
+ return (read(sizeof(T), (u8int*)elem) == sizeof(T));
+ }
+ template <typename T> bool write(T* elem) {
+ return write(sizeof(T), (u8int*)elem);
+ }
+
+ bool seek(u64int count, u8int mode) {
+ union {
+ u64int x;
+ u32int a[2];
+ } wat = {count};
+ return (doCall(FLIF_SEEK, wat.a[0], wat.a[1], mode) != 0);
+ }
+ u64int position() {
+ return *((u64int*)doCall(FLIF_POSITION));
+ }
+ u64int length() {
+ return *((u64int*)doCall(FLIF_LENGTH));
+ }
+ bool eof() {
+ return (doCall(FLIF_EOF) != 0);
+ }
+};
+
+#endif
diff --git a/Source/Library/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h
index ddca6be..9687ea9 100644
--- a/Source/Library/Userland/Binding/Process.class.h
+++ b/Source/Library/Userland/Binding/Process.class.h
@@ -29,8 +29,11 @@ class Process : public RessourceCaller {
u32int getPpid() {
return doCall(PRIF_GETPPID);
}
- String getCmdline() {
- return String::unserialize(doCall(PRIF_GETCMDLINE));
+ u32int argc() {
+ return doCall(PRIF_ARGC);
+ }
+ String argv(u32int idx) {
+ return String::unserialize(doCall(PRIF_ARGV, idx));
}
};
diff --git a/Source/Library/Userland/Binding/Sys.ns.cpp b/Source/Library/Userland/Binding/Sys.ns.cpp
deleted file mode 100644
index 7083e56..0000000
--- a/Source/Library/Userland/Binding/Sys.ns.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
index 3a8426b..eb09504 100644
--- a/Source/Library/Userland/Binding/Sys.ns.h
+++ b/Source/Library/Userland/Binding/Sys.ns.h
@@ -1,9 +1,31 @@
#ifndef DEF_SYS_NS_H
#define DEF_SYS_NS_H
+#include <Sys.iface.h>
+#include <Syscall/RessourceCaller.class.h>
+
namespace Sys {
- void halt();
- void reboot();
+
+inline void halt() {
+ RessourceCaller::sCall(SYIF_IFID, SYIF_HALT);
+}
+
+inline void reboot() {
+ RessourceCaller::sCall(SYIF_IFID, SYIF_REBOOT);
+}
+
+inline u32int uptime() { //Returns uptime in seconds
+ return RessourceCaller::sCall(SYIF_IFID, SYIF_UPTIME);
+}
+
+inline u32int totalRam() { //Returns total amount of RAM in Ko
+ return RessourceCaller::sCall(SYIF_IFID, SYIF_TOTALRAM);
+}
+
+inline u32int freeRam() { //Returns free amount of RAM in Ko
+ return RessourceCaller::sCall(SYIF_IFID, SYIF_FREERAM);
+}
+
}
#endif
diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp
index dee7da6..be4f81e 100644
--- a/Source/Library/Userland/Start.cpp
+++ b/Source/Library/Userland/Start.cpp
@@ -13,7 +13,7 @@ Heap heap;
VirtualTerminal invt(0), outvt(0);
-int main();
+int main(const Vector<String>& args);
extern "C" void start() {
//Call static constructors
@@ -24,7 +24,11 @@ extern "C" void start() {
heap.create(0x40000000, 0x00100000, 0x00004000); //Initially create a 1M heap with 16ko index
invt = VirtualTerminal::getIn(); outvt = VirtualTerminal::getOut();
- u32int r = main();
+ u32int argc = Process::get().argc();
+ Vector<String> args(argc);
+ for (u32int i = 0; i < argc; i++) args[i] = Process::get().argv(i);
+
+ u32int r = main(args);
//Call static destructors
for(u32int * call = &start_dtors; call < &end_dtors; call++) {