Noux: skeleton for getpid and fork

This commit is contained in:
Norman Feske 2012-02-15 19:51:13 +01:00
parent f3fcb5f56f
commit 15f0879402
4 changed files with 81 additions and 0 deletions

View File

@ -46,6 +46,8 @@ namespace Noux {
SYSCALL_FCHDIR, SYSCALL_FCHDIR,
SYSCALL_EXECVE, SYSCALL_EXECVE,
SYSCALL_SELECT, SYSCALL_SELECT,
SYSCALL_FORK,
SYSCALL_GETPID,
SYSCALL_INVALID = -1 SYSCALL_INVALID = -1
}; };
@ -66,6 +68,8 @@ namespace Noux {
NOUX_DECL_SYSCALL_NAME(FCHDIR) NOUX_DECL_SYSCALL_NAME(FCHDIR)
NOUX_DECL_SYSCALL_NAME(EXECVE) NOUX_DECL_SYSCALL_NAME(EXECVE)
NOUX_DECL_SYSCALL_NAME(SELECT) NOUX_DECL_SYSCALL_NAME(SELECT)
NOUX_DECL_SYSCALL_NAME(FORK)
NOUX_DECL_SYSCALL_NAME(GETPID)
case SYSCALL_INVALID: return 0; case SYSCALL_INVALID: return 0;
} }
return 0; return 0;

View File

@ -247,6 +247,12 @@ namespace Noux {
SYSIO_DECL(select, { Select_fds fds; Select_timeout timeout; }, SYSIO_DECL(select, { Select_fds fds; Select_timeout timeout; },
{ Select_fds fds; }); { Select_fds fds; });
SYSIO_DECL(fork, { Genode::addr_t ip; Genode::addr_t sp;
Genode::addr_t parent_cap_addr; },
{ int pid; });
SYSIO_DECL(getpid, { }, { int pid; });
}; };
}; };
}; };

View File

@ -293,6 +293,64 @@ extern "C" int select(int nfds, fd_set *readfds, fd_set *writefds,
} }
#include <setjmp.h>
#include <base/crt0.h> /* for '_parent_cap', needed by 'fork' */
#include <base/platform_env.h>
static jmp_buf fork_jmp_buf;
/*
* The new process created via fork will start its execution here.
*/
extern "C" void fork_trampoline()
{
static_cast<Genode::Platform_env *>(Genode::env())->reload_parent_cap();
longjmp(fork_jmp_buf, 1);
}
extern "C" pid_t fork(void)
{
/* stack used for executing 'fork_trampoline' */
enum { STACK_SIZE = 1024 };
static long stack[STACK_SIZE];
if (setjmp(fork_jmp_buf)) {
/* got here via longjmp from 'fork_trampoline' */
PDBG("fork: got here via longjmp");
return 0;
} else {
PDBG("fork: got here via normal control flow");
/* got here during the normal control flow of the fork call */
sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline);
sysio()->fork_in.sp = (Genode::addr_t)(&stack[STACK_SIZE]);
sysio()->fork_in.parent_cap_addr = (Genode::addr_t)(&_parent_cap);
if (!noux()->syscall(Noux::Session::SYSCALL_FORK)) {
PERR("fork error %d", sysio()->error.general);
}
return sysio()->fork_out.pid;
}
}
extern "C" pid_t getpid(void)
{
noux()->syscall(Noux::Session::SYSCALL_GETPID);
return sysio()->getpid_out.pid;
}
/********************* /*********************
** File operations ** ** File operations **
*********************/ *********************/

View File

@ -283,6 +283,19 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
return true; return true;
} }
case SYSCALL_FORK:
{
PDBG("fork called - not implemented");
_sysio->fork_out.pid = 77;
return true;
}
case SYSCALL_GETPID:
{
_sysio->getpid_out.pid = _pid;
return true;
}
case SYSCALL_INVALID: break; case SYSCALL_INVALID: break;
} }
} }