summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-24 22:58:28 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-24 22:58:28 +0200
commitd1ac6fb03e3110e35023f60f643f0c4d02c3d8b6 (patch)
treeb7f693ab8ea9d320f5bd1b838e8eb3d3bcd690f4 /Source
parentb639b99b3e8f4cf77560d8d473b13d992ac8eb10 (diff)
downloadMelon-d1ac6fb03e3110e35023f60f643f0c4d02c3d8b6.tar.gz
Melon-d1ac6fb03e3110e35023f60f643f0c4d02c3d8b6.zip
More work on syscalls : userland applications can run other apps.
Diffstat (limited to 'Source')
-rw-r--r--Source/Applications/Shell/Shell-fs.ns.cpp21
-rw-r--r--Source/Applications/Shell/Shell.ns.cpp5
-rw-r--r--Source/Applications/Shell/Shell.ns.h1
-rw-r--r--Source/Kernel/Shell/KernelShell-fs.class.cpp3
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.cpp4
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp69
-rw-r--r--Source/Kernel/TaskManager/Process.class.h9
-rw-r--r--Source/Library/Interface/Process.iface.h10
-rw-r--r--Source/Library/Userland/Binding/Process.class.h22
-rw-r--r--Source/Library/Userland/Start.cpp12
10 files changed, 145 insertions, 11 deletions
diff --git a/Source/Applications/Shell/Shell-fs.ns.cpp b/Source/Applications/Shell/Shell-fs.ns.cpp
index 1d52836..cd9de8a 100644
--- a/Source/Applications/Shell/Shell-fs.ns.cpp
+++ b/Source/Applications/Shell/Shell-fs.ns.cpp
@@ -1,5 +1,6 @@
#include "Shell.ns.h"
#include <TextFile.class.h>
+#include <Binding/Process.class.h>
namespace Shell {
@@ -112,4 +113,24 @@ void wf(Vector<String>& args) {
}
}
+void run(Vector<String>& args) {
+ if (args.size() == 1) {
+ outvt << "Nothing to run...\n";
+ } else {
+ Process p = Process::run(args[1]);
+ if (p.valid()) {
+ p.setInVT(invt);
+ p.setOutVT(outvt);
+ for (u32int i = 2; i < args.size(); i++) {
+ p.pushArg(args[i]);
+ }
+ p.start();
+ s32int v = p.wait();
+ outvt << "Return value : " << (s64int)v << "\n";
+ } else {
+ outvt << "Error while launching process.\n";
+ }
+ }
+}
+
}
diff --git a/Source/Applications/Shell/Shell.ns.cpp b/Source/Applications/Shell/Shell.ns.cpp
index 7213094..cd091d5 100644
--- a/Source/Applications/Shell/Shell.ns.cpp
+++ b/Source/Applications/Shell/Shell.ns.cpp
@@ -16,8 +16,9 @@ u32int run() {
{"pwd", pwd},
{"rm", rm},
{"mkdir", mkdir},
- {"cat", cat},
- {"wf", wf},
+ {"cat", cat},
+ {"wf", wf},
+ {"run", run},
{"", 0}
};
diff --git a/Source/Applications/Shell/Shell.ns.h b/Source/Applications/Shell/Shell.ns.h
index a22c18d..b2dd587 100644
--- a/Source/Applications/Shell/Shell.ns.h
+++ b/Source/Applications/Shell/Shell.ns.h
@@ -14,4 +14,5 @@ namespace Shell {
extern void mkdir(Vector<String>& args);
extern void cat(Vector<String>& args);
extern void wf(Vector<String>& args);
+ extern void run(Vector<String>& args);
}
diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp
index bc7e137..fa2078d 100644
--- a/Source/Kernel/Shell/KernelShell-fs.class.cpp
+++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp
@@ -109,7 +109,8 @@ void KernelShell::run(Vector<String>& args) {
if (args.size() == 1) {
*m_vt << "No app to run !\n";
} else {
- Process* p = Process::run(args[1], m_cwd, 0);
+ Task::currProcess()->setCwd(m_cwd);
+ Process* p = Process::run(args[1], 0);
if (p == 0) {
*m_vt << "Error while launching process.\n";
} else {
diff --git a/Source/Kernel/SyscallManager/Ressource.class.cpp b/Source/Kernel/SyscallManager/Ressource.class.cpp
index 8862bca..ec9137b 100644
--- a/Source/Kernel/SyscallManager/Ressource.class.cpp
+++ b/Source/Kernel/SyscallManager/Ressource.class.cpp
@@ -1,6 +1,7 @@
#include "Ressource.class.h"
#include <SyscallManager/Res.ns.h>
#include <UserManager/Usr.ns.h>
+#include <TaskManager/Task.ns.h>
Ressource::Ressource(u8int type, call_t* callTable) : m_lock(MUTEX_FALSE) {
m_id = Res::registerRes(this);
@@ -20,8 +21,6 @@ void Ressource::addCallTable(call_t* callTable) {
}
u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) {
- if (id == 0) return m_type;
-
for (SimpleList<call_t*> *iter = m_callTables; iter != 0; iter = iter->next()) {
call_t* ct = iter->v();
u32int i = 0;
@@ -43,6 +42,7 @@ u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32in
u32int Ressource::call(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) {
if (!ISROOT && !accessible()) return (u32int) - 1;
+ if (id == 0) return m_type;
m_lock.waitLock();
u32int r = doCall(id, a, b, c, d, e);
m_lock.unlock();
diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp
index a7e7d7c..eec28d8 100644
--- a/Source/Kernel/TaskManager/Process.class.cpp
+++ b/Source/Kernel/TaskManager/Process.class.cpp
@@ -5,6 +5,8 @@
#include <Linker/Binary.proto.h>
#include <Process.iface.h>
#include <UserManager/Usr.ns.h>
+#include <VirtualTerminal.iface.h>
+#include <SyscallManager/Res.ns.h>
#define ISPARENT Task::currProcess()->getPid() == m_ppid
@@ -20,11 +22,30 @@ call_t Process::m_callTable[] = {
CALL0(PRIF_GETPPID, &Process::getPpid),
CALL0(PRIF_ARGC, &Process::argcSC),
CALL1(PRIF_ARGV, &Process::argvSC),
+ CALL0(PRIF_START, &Process::startSC),
+ CALL1(PRIF_AUTODELETE, &Process::autoDeleteSC),
+ CALL1(PRIF_PUSHARG, &Process::pushArgSC),
+ CALL1(PRIF_SETOUTVT, &Process::setOutVTSC),
+ CALL1(PRIF_SETINVT, &Process::setInVTSC),
CALL0(0, 0)
};
u32int Process::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
if (wat == PRIF_SGETCPR) return Task::currProcess()->resId();
+ if (wat == PRIF_SRUN) {
+ String* e = (String*)a;
+ Process* p = Process::run(*e, Usr::uid());
+ if (p != 0) return p->resId();
+ }
+ if (wat == PRIF_SWAIT) {
+ Process* p = Res::get<Process>(a, PRIF_OBJTYPE);
+ if (Task::currProcess()->getPid() != p->m_ppid) return 0;
+ while (p->m_state != P_FINISHED and !p->m_autodelete) Task::currThread()->sleep(20);
+ if (p->m_autodelete) return E_AUTODELETE;
+ s32int ret = p->m_retval;
+ delete p;
+ return ret;
+ }
return (u32int) - 1;
}
@@ -57,8 +78,8 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) {
return p;
}
-Process* Process::run(String filename, FSNode* cwd, u32int uid) {
- File file(filename, FM_READ, cwd);
+Process* Process::run(String filename, u32int uid) {
+ File file(filename, FM_READ, (FSNode*)Task::currProcess()->getCwd());
if (!file.valid()) return 0;
Binary* b = Binary::load(file);
if (b == 0) return 0;
@@ -81,6 +102,7 @@ Process::Process(String binfile, u32int uid) : Ressource(PRIF_OBJTYPE, m_callTab
m_retval = 0;
m_state = P_STARTING;
m_uid = uid;
+ m_autodelete = false;
m_cwd = Task::currProcess()->getCwd();
m_inVT = Task::currProcess()->getInVT();
m_outVT = Task::currProcess()->getOutVT();
@@ -128,7 +150,12 @@ void Process::registerThread(Thread* t) {
void Process::threadFinishes(Thread* thread, u32int retval) {
// If it is the main thread of the process, or if it pagefaulted
if (thread == m_threads[0] or retval == E_PAGEFAULT or retval == E_EXIT) {
- exit();
+ m_retval = retval;
+ if (m_autodelete) {
+ delete this;
+ } else {
+ exit();
+ }
} else {
//Simply unregister thread
for (u32int i = 0; i < m_threads.size(); i++) {
@@ -206,6 +233,42 @@ u32int Process::freePageSC(u32int pos) {
m_pagedir->freeFrame(pos);
return 0;
}
+
+u32int Process::startSC() {
+ if (Task::currProcess()->getPid() == m_ppid) {
+ start();
+ return 1;
+ }
+ return 0;
+}
+
+u32int Process::autoDeleteSC(u32int d) {
+ if (Task::currProcess()->getPid() != m_ppid) return 2;
+ m_autodelete = (d != 0);
+ return (m_autodelete ? 1 : 0);
+}
+
+u32int Process::pushArgSC(u32int arg) {
+ String* a = (String*)arg;
+ m_arguments.push(*a);
+ return 0;
+}
+
+u32int Process::setInVTSC(u32int vtid) {
+ if (Task::currProcess()->getPid() != m_ppid) return 0;
+ VirtualTerminal* vt = Res::get<VirtualTerminal>(vtid, VTIF_OBJTYPE);
+ if (vt != 0) setInVT(vt);
+ return 1;
+}
+
+u32int Process::setOutVTSC(u32int vtid) {
+ if (Task::currProcess()->getPid() != m_ppid) return 0;
+ VirtualTerminal* vt = Res::get<VirtualTerminal>(vtid, VTIF_OBJTYPE);
+ if (vt != 0) setOutVT(vt);
+ return 1;
+}
+
+
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 ec5a90d..11da57b 100644
--- a/Source/Kernel/TaskManager/Process.class.h
+++ b/Source/Kernel/TaskManager/Process.class.h
@@ -45,6 +45,8 @@ class Process : public Ressource {
VirtualTerminal *m_inVT, *m_outVT;
DirectoryNode *m_cwd;
+ bool m_autodelete;
+
Heap *m_userHeap;
Vector<Thread*> m_threads;
@@ -57,13 +59,18 @@ class Process : public Ressource {
u32int argvSC(u32int);
u32int allocPageSC(u32int);
u32int freePageSC(u32int);
+ u32int startSC(); //Permits parent process to start run of process
+ u32int autoDeleteSC(u32int); //If true, process will auto-delete when it finishes. Else, it must be deleted by parent, while waiting for it.
+ u32int pushArgSC(u32int);
+ u32int setOutVTSC(u32int);
+ u32int setInVTSC(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);
+ static Process* run(String filename, u32int uid);
Process(String binfile, u32int uid);
~Process();
diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h
index 52543aa..0152947 100644
--- a/Source/Library/Interface/Process.iface.h
+++ b/Source/Library/Interface/Process.iface.h
@@ -1,10 +1,14 @@
#ifndef DEF_PROCESS_IFACE_H
#define DEF_PROCESS_IFACE_H
+#define E_AUTODELETE 0x0FFFFF03
+
#define PRIF_OBJTYPE 0x20
//S = static, GET = get, C = current, PR = process
#define PRIF_SGETCPR 0
+#define PRIF_SRUN 1
+#define PRIF_SWAIT 2
#define PRIF_EXIT 0x01
#define PRIF_ALLOCPAGE 0x02
@@ -15,4 +19,10 @@
#define PRIF_ARGC 0x10
#define PRIF_ARGV 0x11
+#define PRIF_START 0x20
+#define PRIF_AUTODELETE 0x21
+#define PRIF_PUSHARG 0x28
+#define PRIF_SETOUTVT 0x29
+#define PRIF_SETINVT 0x30
+
#endif
diff --git a/Source/Library/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h
index 9687ea9..a3fc569 100644
--- a/Source/Library/Userland/Binding/Process.class.h
+++ b/Source/Library/Userland/Binding/Process.class.h
@@ -2,6 +2,7 @@
#define DEF_PROCESS_CLASS_H
#include <Syscall/RessourceCaller.class.h>
+#include <Binding/VirtualTerminal.class.h>
#include <Process.iface.h>
#include <String.class.h>
@@ -12,6 +13,9 @@ class Process : public RessourceCaller {
u32int id = RessourceCaller::sCall(PRIF_OBJTYPE, PRIF_SGETCPR);
return Process(id);
}
+ static Process run(const String& app) {
+ return Process(sCall(PRIF_OBJTYPE, PRIF_SRUN, (u32int)&app));
+ }
Process(u32int id) : RessourceCaller(id, PRIF_OBJTYPE) {}
void exit() {
@@ -35,6 +39,24 @@ class Process : public RessourceCaller {
String argv(u32int idx) {
return String::unserialize(doCall(PRIF_ARGV, idx));
}
+ void start() {
+ doCall(PRIF_START);
+ }
+ s32int wait() {
+ return sCall(PRIF_OBJTYPE, PRIF_SWAIT, resId());
+ }
+ void autoDelete(bool ad = true) {
+ doCall(PRIF_AUTODELETE, (ad ? 1 : 0));
+ }
+ void pushArg(const String& arg) {
+ doCall(PRIF_PUSHARG, (u32int)&arg);
+ }
+ void setInVT(VirtualTerminal vt) {
+ doCall(PRIF_SETINVT, vt.resId());
+ }
+ void setOutVT(VirtualTerminal vt) {
+ doCall(PRIF_SETOUTVT, vt.resId());
+ }
};
#endif
diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp
index be4f81e..930c4dd 100644
--- a/Source/Library/Userland/Start.cpp
+++ b/Source/Library/Userland/Start.cpp
@@ -1,4 +1,5 @@
#include <types.h>
+#include <Syscall/Syscall.wtf.h>
#include <Binding/VirtualTerminal.class.h>
#include <Heap.class.h>
@@ -15,14 +16,21 @@ VirtualTerminal invt(0), outvt(0);
int main(const Vector<String>& args);
+void doExit(u32int v) {
+ asm volatile("int $66" : : "a"(v));
+}
+
extern "C" void start() {
//Call static constructors
+ u32int i = 0;
for(u32int * call = &start_ctors; call < &end_ctors; call++) {
((void (*)(void))*call)();
}
- heap.create(0x40000000, 0x00100000, 0x00004000); //Initially create a 1M heap with 16ko index
+ heap.create(0x40000000, 0x00040000, 0x00004000); //Initially create a 256ko heap with 16ko index
invt = VirtualTerminal::getIn(); outvt = VirtualTerminal::getOut();
+ if (!invt.valid()) doExit(1);
+ if (!outvt.valid()) doExit(2);
u32int argc = Process::get().argc();
Vector<String> args(argc);
@@ -35,7 +43,7 @@ extern "C" void start() {
((void (*)(void))*call)();
}
- asm volatile("int $66" : : "a"(r));
+ doExit(r);
}
namespace Mem {