From b639b99b3e8f4cf77560d8d473b13d992ac8eb10 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sat, 24 Oct 2009 18:24:46 +0200 Subject: More work on userland syscalls : Files are implemented. TextFile now is a common (= kernel and userland) library. --- Source/Applications/SampleApps/Makefile | 12 ++--- Source/Applications/SampleApps/cxxdemo.cpp | 5 +- Source/Applications/Shell/Help.txt | 2 +- Source/Applications/Shell/Makefile | 6 +-- Source/Applications/Shell/Shell-fs.ns.cpp | 35 +++++++++++++ Source/Applications/Shell/Shell.ns.cpp | 10 ++++ Source/Applications/Shell/Shell.ns.h | 2 + Source/Applications/Shell/main.cpp | 2 +- Source/Kernel/Core/Log.ns.h | 2 +- Source/Kernel/Core/Sys.ns.cpp | 5 ++ Source/Kernel/Core/kmain.wtf.cpp | 1 - Source/Kernel/Makefile | 4 +- Source/Kernel/Shell/KernelShell-fs.class.cpp | 3 ++ Source/Kernel/SyscallManager/Res.ns.cpp | 2 + Source/Kernel/TaskManager/Process.class.cpp | 42 ++++++++------- Source/Kernel/TaskManager/Process.class.h | 4 +- Source/Kernel/UserManager/Usr.ns.cpp | 11 +++- Source/Kernel/VFS/FSNode-sc.proto.cpp | 4 +- Source/Kernel/VFS/File-sc.class.cpp | 68 +++++++++++++++++++++++++ Source/Kernel/VFS/File.class.cpp | 29 ++++++++--- Source/Kernel/VFS/File.class.h | 39 +++++++------- Source/Kernel/VFS/FileNode.class.h | 2 +- Source/Kernel/VFS/TextFile.class.cpp | 21 -------- Source/Kernel/VFS/TextFile.class.h | 21 -------- Source/Kernel/VFS/VFS.ns.cpp | 43 ++-------------- Source/Kernel/VFS/VFS.ns.h | 5 +- Source/Kernel/VTManager/FileVT.class.h | 2 +- Source/Library/Common/TextFile.class.cpp | 30 +++++++++++ Source/Library/Common/TextFile.class.h | 31 +++++++++++ Source/Library/Interface/File.iface.h | 33 ++++++++++++ Source/Library/Interface/Process.iface.h | 4 +- Source/Library/Interface/Sys.iface.h | 3 ++ Source/Library/Link.ld | 1 + Source/Library/Makefile | 5 +- Source/Library/Userland/Binding/FSNode.class.h | 1 + Source/Library/Userland/Binding/File.class.h | 68 +++++++++++++++++++++++++ Source/Library/Userland/Binding/Process.class.h | 7 ++- Source/Library/Userland/Binding/Sys.ns.cpp | 15 ------ Source/Library/Userland/Binding/Sys.ns.h | 26 +++++++++- Source/Library/Userland/Start.cpp | 8 ++- 40 files changed, 440 insertions(+), 174 deletions(-) create mode 100644 Source/Kernel/VFS/File-sc.class.cpp delete mode 100644 Source/Kernel/VFS/TextFile.class.cpp delete mode 100644 Source/Kernel/VFS/TextFile.class.h create mode 100644 Source/Library/Common/TextFile.class.cpp create mode 100644 Source/Library/Common/TextFile.class.h create mode 100644 Source/Library/Interface/File.iface.h create mode 100644 Source/Library/Userland/Binding/File.class.h delete mode 100644 Source/Library/Userland/Binding/Sys.ns.cpp (limited to 'Source') 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 -#include +#include #include #include +#include -int main() { +int main(const Vector& 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 namespace Shell { @@ -77,4 +78,38 @@ void mkdir(Vector& args) { } } +void cat(Vector& 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& 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 .\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& args); extern void rm(Vector& args); extern void mkdir(Vector& args); + extern void cat(Vector& args); + extern void wf(Vector& 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& 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 +#include #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 #include #include +#include +#include #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 #include #include -#include #include #include 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& 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 #include #include +#include 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 #include +#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 *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 #include #include #include -#include +#include /* * 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(b, FNIF_OBJTYPE)); + n = VFS::createDirectory(*path, Res::get(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 +#include +#include +#include + +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(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 #include -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 #include +#include +#include +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/TextFile.class.h b/Source/Kernel/VFS/TextFile.class.h deleted file mode 100644 index a0cd505..0000000 --- a/Source/Kernel/VFS/TextFile.class.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef DEF_TEXTFILE_CLASS_H -#define DEF_TEXTFILE_CLASS_H - -#include - -class TextFile : public File { - private: - u8int m_encoding; - - public: - 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; } - ~TextFile() {} - - void setEncoding(u8int encoding = UE_UTF8) { m_encoding = encoding; } - bool write(String str, bool addnl = false); // Addnl = wether or not to add \n at end - String readLine(char separator = '\n'); -}; - -#endif 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 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 +#include #include 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/Library/Common/TextFile.class.h b/Source/Library/Common/TextFile.class.h new file mode 100644 index 0000000..3749b6a --- /dev/null +++ b/Source/Library/Common/TextFile.class.h @@ -0,0 +1,31 @@ +#ifndef DEF_TEXTFILE_CLASS_H +#define DEF_TEXTFILE_CLASS_H + +#ifdef THIS_IS_MELON_KERNEL +#include +#else +#include +#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; } + bool write(String str, bool addnl = false); // Addnl = wether or not to add \n at end + String readLine(char separator = '\n'); +}; + +#endif 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 +#include #include 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 +#include +#include +#include +#include + +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 bool read(T* elem) { + return (read(sizeof(T), (u8int*)elem) == sizeof(T)); + } + template 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 -#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 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 +#include + 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& 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 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++) { -- cgit v1.2.3