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