diff options
author | Alexis211 <alexis211@gmail.com> | 2009-10-24 22:58:28 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-10-24 22:58:28 +0200 |
commit | d1ac6fb03e3110e35023f60f643f0c4d02c3d8b6 (patch) | |
tree | b7f693ab8ea9d320f5bd1b838e8eb3d3bcd690f4 /Source/Kernel | |
parent | b639b99b3e8f4cf77560d8d473b13d992ac8eb10 (diff) | |
download | Melon-d1ac6fb03e3110e35023f60f643f0c4d02c3d8b6.tar.gz Melon-d1ac6fb03e3110e35023f60f643f0c4d02c3d8b6.zip |
More work on syscalls : userland applications can run other apps.
Diffstat (limited to 'Source/Kernel')
-rw-r--r-- | Source/Kernel/Shell/KernelShell-fs.class.cpp | 3 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Ressource.class.cpp | 4 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Process.class.cpp | 69 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Process.class.h | 9 |
4 files changed, 78 insertions, 7 deletions
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(); |