diff --git a/repos/ports/include/noux_session/capability.h b/repos/ports/include/noux_session/capability.h
deleted file mode 100644
index 37afc81e73..0000000000
--- a/repos/ports/include/noux_session/capability.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * \brief Noux-session capability type
- * \author Norman Feske
- * \date 2011-02-15
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__NOUX_SESSION__CAPABILITY_H_
-#define _INCLUDE__NOUX_SESSION__CAPABILITY_H_
-
-#include
-#include
-
-namespace Noux { typedef Capability Session_capability; }
-
-#endif /* _INCLUDE__NOUX_SESSION__CAPABILITY_H_ */
diff --git a/repos/ports/include/noux_session/client.h b/repos/ports/include/noux_session/client.h
deleted file mode 100644
index 5eb40faebd..0000000000
--- a/repos/ports/include/noux_session/client.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * \brief Noux-session client interface
- * \author Norman Feske
- * \date 2011-02-15
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__NOUX_SESSION__CLIENT_H_
-#define _INCLUDE__NOUX_SESSION__CLIENT_H_
-
-#include
-#include
-#include
-#include
-
-namespace Noux {
-
- struct Session_client : Rpc_client
- {
- explicit Session_client(Session_capability session)
- : Rpc_client(session) { }
-
-
- Dataspace_capability sysio_dataspace()
- {
- return call();
- }
-
- bool syscall(Syscall sc)
- {
- static bool verbose = false;
-
- bool result = call(sc);
-
- if ((result == false) && verbose)
- error("syscall ", syscall_name(sc), " failed");
-
- return result;
- }
-
- int next_open_fd(int start_fd)
- {
- return call(start_fd);
- }
-
- Capability lookup_region_map(addr_t const addr)
- {
- return call(addr);
- }
- };
-}
-
-#endif /* _INCLUDE__NOUX_SESSION__CLIENT_H_ */
diff --git a/repos/ports/include/noux_session/connection.h b/repos/ports/include/noux_session/connection.h
deleted file mode 100644
index d8b73a031a..0000000000
--- a/repos/ports/include/noux_session/connection.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * \brief Noux connection
- * \author Norman Feske
- * \date 2011-02-15
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__NOUX_SESSION__CONNECTION_H_
-#define _INCLUDE__NOUX_SESSION__CONNECTION_H_
-
-#include
-#include
-
-namespace Noux { struct Connection; }
-
-
-struct Noux::Connection : Genode::Connection, Session_client
-{
- /**
- * Constructor
- */
- Connection(Genode::Env &env)
- :
- Genode::Connection(env, session(env.parent(), "")),
- Session_client(cap())
- { }
-
- /**
- * Remove session ID of the noux session from the ID space.
- *
- * This must by done before reinitializing the noux connection in a
- * freshly forked process. Otherwise, an overwritten 'Noux::Connection'
- * object would still be referenced by the AVL tree of the the ID space.
- */
- void discard_session_id()
- {
- _id_space_element.~Element();
- }
-};
-
-#endif /* _INCLUDE__NOUX_SESSION__CONNECTION_H_ */
diff --git a/repos/ports/include/noux_session/noux_session.h b/repos/ports/include/noux_session/noux_session.h
deleted file mode 100644
index 2911333de3..0000000000
--- a/repos/ports/include/noux_session/noux_session.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * \brief Noux session interface
- * \author Norman Feske
- * \date 2011-02-15
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__NOUX_SESSION__NOUX_SESSION_H_
-#define _INCLUDE__NOUX_SESSION__NOUX_SESSION_H_
-
-#include
-#include
-#include
-#include
-
-#define NOUX_DECL_SYSCALL_NAME(name) \
- case SYSCALL_##name: return #name;
-
-namespace Noux {
-
- using namespace Genode;
-
- struct Session : Genode::Session
- {
- static const char *service_name() { return "Noux"; }
-
- enum { CAP_QUOTA = 3 };
-
- virtual ~Session() { }
-
- virtual Dataspace_capability sysio_dataspace() = 0;
-
- /**
- * Return leaf region map that covers a given address
- *
- * \param addr address that is covered by the requested region map
- */
- virtual Capability lookup_region_map(addr_t const addr) = 0;
-
- enum Syscall {
- SYSCALL_WRITE,
- SYSCALL_READ,
- SYSCALL_STAT,
- SYSCALL_LSTAT,
- SYSCALL_FSTAT,
- SYSCALL_FTRUNCATE,
- SYSCALL_FCNTL,
- SYSCALL_OPEN,
- SYSCALL_CLOSE,
- SYSCALL_IOCTL,
- SYSCALL_LSEEK,
- SYSCALL_DIRENT,
- SYSCALL_EXECVE,
- SYSCALL_SELECT,
- SYSCALL_FORK,
- SYSCALL_GETPID,
- SYSCALL_WAIT4,
- SYSCALL_PIPE,
- SYSCALL_DUP2,
- SYSCALL_UNLINK,
- SYSCALL_READLINK,
- SYSCALL_RENAME,
- SYSCALL_MKDIR,
- SYSCALL_SYMLINK,
- SYSCALL_SOCKET,
- SYSCALL_GETSOCKOPT,
- SYSCALL_SETSOCKOPT,
- SYSCALL_ACCEPT,
- SYSCALL_BIND,
- SYSCALL_LISTEN,
- SYSCALL_SEND,
- SYSCALL_SENDTO,
- SYSCALL_RECV,
- SYSCALL_RECVFROM,
- SYSCALL_GETPEERNAME,
- SYSCALL_SHUTDOWN,
- SYSCALL_CONNECT,
- SYSCALL_USERINFO,
- SYSCALL_GETTIMEOFDAY,
- SYSCALL_CLOCK_GETTIME,
- SYSCALL_UTIMES,
- SYSCALL_SYNC,
- SYSCALL_KILL,
- SYSCALL_GETDTABLESIZE,
- SYSCALL_INVALID = -1
- };
-
- static char const *syscall_name(Syscall sc)
- {
- switch (sc) {
- NOUX_DECL_SYSCALL_NAME(WRITE)
- NOUX_DECL_SYSCALL_NAME(READ)
- NOUX_DECL_SYSCALL_NAME(STAT)
- NOUX_DECL_SYSCALL_NAME(LSTAT)
- NOUX_DECL_SYSCALL_NAME(FSTAT)
- NOUX_DECL_SYSCALL_NAME(FTRUNCATE)
- NOUX_DECL_SYSCALL_NAME(FCNTL)
- NOUX_DECL_SYSCALL_NAME(OPEN)
- NOUX_DECL_SYSCALL_NAME(CLOSE)
- NOUX_DECL_SYSCALL_NAME(IOCTL)
- NOUX_DECL_SYSCALL_NAME(LSEEK)
- NOUX_DECL_SYSCALL_NAME(DIRENT)
- NOUX_DECL_SYSCALL_NAME(EXECVE)
- NOUX_DECL_SYSCALL_NAME(SELECT)
- NOUX_DECL_SYSCALL_NAME(FORK)
- NOUX_DECL_SYSCALL_NAME(GETPID)
- NOUX_DECL_SYSCALL_NAME(WAIT4)
- NOUX_DECL_SYSCALL_NAME(PIPE)
- NOUX_DECL_SYSCALL_NAME(DUP2)
- NOUX_DECL_SYSCALL_NAME(UNLINK)
- NOUX_DECL_SYSCALL_NAME(READLINK)
- NOUX_DECL_SYSCALL_NAME(RENAME)
- NOUX_DECL_SYSCALL_NAME(MKDIR)
- NOUX_DECL_SYSCALL_NAME(SYMLINK)
- NOUX_DECL_SYSCALL_NAME(SOCKET)
- NOUX_DECL_SYSCALL_NAME(GETSOCKOPT)
- NOUX_DECL_SYSCALL_NAME(SETSOCKOPT)
- NOUX_DECL_SYSCALL_NAME(ACCEPT)
- NOUX_DECL_SYSCALL_NAME(BIND)
- NOUX_DECL_SYSCALL_NAME(LISTEN)
- NOUX_DECL_SYSCALL_NAME(SEND)
- NOUX_DECL_SYSCALL_NAME(SENDTO)
- NOUX_DECL_SYSCALL_NAME(RECV)
- NOUX_DECL_SYSCALL_NAME(RECVFROM)
- NOUX_DECL_SYSCALL_NAME(GETPEERNAME)
- NOUX_DECL_SYSCALL_NAME(SHUTDOWN)
- NOUX_DECL_SYSCALL_NAME(CONNECT)
- NOUX_DECL_SYSCALL_NAME(USERINFO)
- NOUX_DECL_SYSCALL_NAME(GETTIMEOFDAY)
- NOUX_DECL_SYSCALL_NAME(CLOCK_GETTIME)
- NOUX_DECL_SYSCALL_NAME(UTIMES)
- NOUX_DECL_SYSCALL_NAME(SYNC)
- NOUX_DECL_SYSCALL_NAME(KILL)
- NOUX_DECL_SYSCALL_NAME(GETDTABLESIZE)
- case SYSCALL_INVALID: return 0;
- }
- return 0;
- }
-
- /**
- * Perform syscall
- *
- * The syscall arguments and results are communicated via the shared
- * sysio dataspace.
- *
- * \return true on success
- */
- virtual bool syscall(Syscall syscall) = 0;
-
- /*
- * Return the next open file descriptor, starting from (and including)
- * 'start_fd'.
- *
- * \return the next open file descriptor or -1
- */
- virtual int next_open_fd(int start_fd) = 0;
-
- /*********************
- ** RPC declaration **
- *********************/
-
- GENODE_RPC(Rpc_sysio_dataspace, Dataspace_capability, sysio_dataspace);
- GENODE_RPC(Rpc_lookup_region_map, Capability,
- lookup_region_map, addr_t);
- GENODE_RPC(Rpc_syscall, bool, syscall, Syscall);
- GENODE_RPC(Rpc_next_open_fd, int, next_open_fd, int);
-
- GENODE_RPC_INTERFACE(Rpc_sysio_dataspace, Rpc_lookup_region_map,
- Rpc_syscall, Rpc_next_open_fd);
- };
-}
-
-#undef NOUX_DECL_SYSCALL_NAME
-
-#endif /* _INCLUDE__NOUX_SESSION__NOUX_SESSION_H_ */
-
diff --git a/repos/ports/include/noux_session/sysio.h b/repos/ports/include/noux_session/sysio.h
deleted file mode 100644
index 9ec3f8d544..0000000000
--- a/repos/ports/include/noux_session/sysio.h
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * \brief Facility for passing system-call arguments
- * \author Norman Feske
- * \date 2011-02-15
- *
- * The 'Sysio' data structure is shared between the noux environment
- * and the child. It is used to pass system-call arguments that would
- * traditionally be transferred via 'copy_from_user' and 'copy_to_user'.
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__NOUX_SESSION__SYSIO_H_
-#define _INCLUDE__NOUX_SESSION__SYSIO_H_
-
-/* Genode includes */
-#include
-#include
-#include
-
-
-#define SYSIO_DECL(syscall_name, args, results) \
- struct args syscall_name##_in; \
- struct results syscall_name##_out;
-
-
-namespace Noux {
- using namespace Genode;
- struct Sysio;
-}
-
-
-struct Noux::Sysio
-{
- /* signal numbers must match with libc signal numbers */
- enum Signal {
- SIG_INT = 2,
- SIG_CHLD = 20,
- SIG_WINCH = 28
- };
-
- enum { SIGNAL_QUEUE_SIZE = 32 };
- Ring_buffer pending_signals;
-
- enum { MAX_PATH_LEN = 512 };
- typedef char Path[MAX_PATH_LEN];
-
- enum { CHUNK_SIZE = 64*1024 };
- typedef char Chunk[CHUNK_SIZE];
-
- enum { ARGS_MAX_LEN = 16*1024 };
- typedef char Args[ARGS_MAX_LEN];
-
- enum { ENV_MAX_LEN = 6*1024 };
- typedef char Env[ENV_MAX_LEN];
-
- typedef __SIZE_TYPE__ size_t;
- typedef long int ssize_t;
-
- /**
- * Flags of 'mode' argument of open syscall
- */
- enum {
- OPEN_MODE_RDONLY = 0,
- OPEN_MODE_WRONLY = 1,
- OPEN_MODE_RDWR = 2,
- OPEN_MODE_ACCMODE = 3,
- OPEN_MODE_CREATE = 0x0800, /* libc O_EXCL */
- };
-
- typedef Vfs::Directory_service::Stat Stat;
-
- /**
- * Argument structure used for ioctl syscall
- */
- struct Ioctl_in
- {
- typedef Vfs::File_io_service::Ioctl_opcode Opcode;
-
- typedef Vfs::File_io_service::Ioctl_value Value;
-
- Opcode request;
- int argp;
- };
-
- /**
- * Structure carrying the result values of 'ioctl' syscalls
- */
- typedef Vfs::File_io_service::Ioctl_out Ioctl_out;
-
- enum Lseek_whence { LSEEK_SET, LSEEK_CUR, LSEEK_END };
-
- enum { DIRENT_MAX_NAME_LEN = Vfs::Directory_service::Dirent::Name::MAX_LEN };
-
- typedef Vfs::Directory_service::Dirent_type Dirent_type;
-
- /*
- * Must be POD (in contrast to the VFS type) because it's used in a union
- */
- struct Dirent
- {
- unsigned long fileno;
- Dirent_type type;
- char name[DIRENT_MAX_NAME_LEN];
-
- Dirent & operator= (Vfs::Directory_service::Dirent const &dirent)
- {
- fileno = dirent.fileno;
- type = dirent.type;
- memcpy(name, dirent.name.buf, DIRENT_MAX_NAME_LEN);
-
- return *this;
- }
- };
-
- enum Fcntl_cmd {
- FCNTL_CMD_GET_FILE_STATUS_FLAGS,
- FCNTL_CMD_SET_FILE_STATUS_FLAGS,
- FCNTL_CMD_SET_FD_FLAGS,
- FCNTL_CMD_GET_FD_FLAGS
- };
-
- enum {
- FCNTL_FILE_STATUS_FLAG_NONBLOCK = 4
- };
-
- /**
- * Input and output argument type of select syscall
- */
- struct Select_fds
- {
- /**
- * Maximum number of file descriptors supported
- */
- enum { MAX_FDS = 32U };
-
- /**
- * Number of file descriptors to watch for read operations (rd),
- * write operations (wr), or exceptions (ex).
- */
- size_t num_rd,
- num_wr,
- num_ex;
-
- /**
- * Array containing the file descriptors, starting with those
- * referring to rd, followed by wr, and finally ex
- */
- int array[MAX_FDS];
-
- /**
- * Return total number of file descriptors contained in the array
- */
- size_t total_fds() const {
- return min(num_rd + num_wr + num_ex, (size_t)MAX_FDS); }
-
- /**
- * Check for maximum population of fds array
- */
- bool max_fds_exceeded() const
- {
- /*
- * Note that even though the corner case of num_rd + num_wr +
- * num_ex == MAX_FDS is technically valid, this condition hints
- * at a possible attempt to over popupate the array (see the
- * implementation of 'select' in the Noux libc plugin). Hence,
- * we regard this case as an error, too.
- */
- return total_fds() >= MAX_FDS;
- }
-
- /**
- * Return true of fd set index should be watched for reading
- */
- bool watch_for_rd(unsigned i) const { return i < num_rd; }
-
- /**
- * Return true if fd set index should be watched for writing
- */
- bool watch_for_wr(unsigned i) const {
- return (i >= num_rd) && (i < num_rd + num_wr); }
-
- /**
- * Return true if fd set index should be watched for exceptions
- */
- bool watch_for_ex(unsigned i) const {
- return (i >= num_rd + num_wr) && (i < total_fds()); }
- };
-
- struct Select_timeout
- {
- long sec, usec;
-
- /**
- * Set timeout to infinity
- */
- void set_infinite() { sec = -1; usec = -1; }
-
- /**
- * Return true if the timeout is infinite
- */
- bool infinite() const { return (sec == -1) && (usec == -1); }
-
- /**
- * Return true if the timeout is zero
- */
- bool zero() const { return (sec == 0) && (usec == 0); }
- };
-
- /**
- * Socket related structures
- */
- enum { MAX_HOSTNAME_LEN = 255 };
- typedef char Hostname[MAX_HOSTNAME_LEN];
-
- enum { MAX_SERVNAME_LEN = 255 };
- typedef char Servname[MAX_SERVNAME_LEN];
-
- enum { MAX_ADDRINFO_RESULTS = 4 };
-
- struct in_addr
- {
- unsigned int s_addr;
- };
-
- struct sockaddr
- {
- unsigned char sa_len;
- unsigned char sa_family;
- char sa_data[14];
- };
-
- struct sockaddr_in {
- unsigned char sin_len;
- unsigned char sin_family;
- unsigned short sin_port;
- struct in_addr sin_addr;
- char sin_zero[8];
- };
-
- typedef unsigned socklen_t;
-
- struct addrinfo {
- int ai_flags;
- int ai_family;
- int ai_socktype;
- int ai_protocol;
- socklen_t ai_addrlen;
- struct sockaddr *ai_addr;
- char *ai_canonname;
- struct addrinfo *ai_next;
- };
-
- struct Addrinfo {
- struct addrinfo addrinfo;
- struct sockaddr ai_addr;
- char ai_canonname[255];
- };
-
- /**
- * user info defintions
- */
- enum { USERINFO_GET_ALL = 0, USERINFO_GET_UID, USERINFO_GET_GID };
- enum { MAX_USERNAME_LEN = 32 };
- typedef char User[MAX_USERNAME_LEN];
- enum { MAX_SHELL_LEN = 16 };
- typedef char Shell[MAX_SHELL_LEN];
- enum { MAX_HOME_LEN = 128 };
- typedef char Home[MAX_HOME_LEN];
- typedef unsigned int Uid;
-
- /**
- * time/clock definitions
- */
- enum Clock_Id { CLOCK_ID_SECOND };
-
- enum Fcntl_error { FCNTL_ERR_CMD_INVALID = Vfs::Directory_service::NUM_GENERAL_ERRORS };
- enum Mkdir_error { MKDIR_ERR_EXISTS, MKDIR_ERR_NO_ENTRY,
- MKDIR_ERR_NO_SPACE, MKDIR_ERR_NO_PERM,
- MKDIR_ERR_NAME_TOO_LONG };
- enum Readlink_error { READLINK_ERR_NO_ENTRY, READLINK_ERR_NO_PERM };
- enum Symlink_error { SYMLINK_ERR_EXISTS, SYMLINK_ERR_NO_ENTRY,
- SYMLINK_ERR_NO_SPACE, SYMLINK_ERR_NO_PERM,
- SYMLINK_ERR_NAME_TOO_LONG };
-
- enum Execve_error { EXECVE_ERR_NO_ENTRY = Vfs::Directory_service::NUM_GENERAL_ERRORS,
- EXECVE_ERR_NO_MEMORY,
- EXECVE_ERR_NO_EXEC,
- EXECVE_ERR_ACCESS};
- enum Fork_error { FORK_NOMEM = Vfs::Directory_service::NUM_GENERAL_ERRORS };
- enum Select_error { SELECT_ERR_INTERRUPT };
-
- /**
- * Socket related errors
- */
- enum Accept_error { ACCEPT_ERR_AGAIN, ACCEPT_ERR_WOULD_BLOCK,
- ACCEPT_ERR_INVALID, ACCEPT_ERR_NO_MEMORY,
- ACCEPT_ERR_NOT_SUPPORTED };
-
- enum Bind_error { BIND_ERR_ACCESS, BIND_ERR_ADDR_IN_USE,
- BIND_ERR_INVALID, BIND_ERR_NO_MEMORY };
-
- enum Connect_error { CONNECT_ERR_ACCESS, CONNECT_ERR_AGAIN,
- CONNECT_ERR_ALREADY, CONNECT_ERR_CONN_REFUSED,
- CONNECT_ERR_NO_PERM, CONNECT_ERR_ADDR_IN_USE,
- CONNECT_ERR_IN_PROGRESS, CONNECT_ERR_IS_CONNECTED,
- CONNECT_ERR_RESET, CONNECT_ERR_ABORTED,
- CONNECT_ERR_NO_ROUTE };
-
- enum Listen_error { LISTEN_ERR_ADDR_IN_USE, LISTEN_ERR_NOT_SUPPORTED };
-
- enum Recv_error { RECV_ERR_AGAIN, RECV_ERR_WOULD_BLOCK,
- RECV_ERR_CONN_REFUSED, RECV_ERR_INVALID,
- RECV_ERR_NOT_CONNECTED, RECV_ERR_NO_MEMORY };
-
- enum Send_error { SEND_ERR_AGAIN, SEND_ERR_WOULD_BLOCK,
- SEND_ERR_CONNECTION_RESET, SEND_ERR_INVALID,
- SEND_ERR_IS_CONNECTED, SEND_ERR_NO_MEMORY };
-
- enum Shutdown_error { SHUTDOWN_ERR_NOT_CONNECTED };
-
- enum Socket_error { SOCKET_ERR_ACCESS, SOCKET_ERR_NO_AF_SUPPORT,
- SOCKET_ERR_INVALID, SOCKET_ERR_NO_MEMORY };
-
- enum Clock_error { CLOCK_ERR_INVALID, CLOCK_ERR_FAULT, CLOCK_ERR_NO_PERM };
-
- enum Utimes_error { UTIMES_ERR_ACCESS, UTIMES_ERR_FAUL, UTIMES_ERR_EIO,
- UTIMES_ERR_NAME_TOO_LONG, UTIMES_ERR_NO_ENTRY,
- UTIMES_ERR_NOT_DIRECTORY, UTIMES_ERR_NO_PERM,
- UTIMES_ERR_READ_ONLY };
-
- enum Wait4_error { WAIT4_ERR_INTERRUPT };
-
- enum Kill_error { KILL_ERR_SRCH };
-
- union {
- Vfs::Directory_service::General_error general;
- Vfs::Directory_service::Stat_result stat;
- Vfs::File_io_service::Ftruncate_result ftruncate;
- Vfs::Directory_service::Open_result open;
- Vfs::Directory_service::Unlink_result unlink;
- Vfs::Directory_service::Rename_result rename;
- Vfs::File_io_service::Read_result read;
- Vfs::File_io_service::Write_result write;
- Vfs::File_io_service::Ioctl_result ioctl;
-
- Fcntl_error fcntl;
- Mkdir_error mkdir;
- Readlink_error readlink;
- Symlink_error symlink;
- Execve_error execve;
- Select_error select;
- Accept_error accept;
- Bind_error bind;
- Connect_error connect;
- Listen_error listen;
- Recv_error recv;
- Send_error send;
- Shutdown_error shutdown;
- Socket_error socket;
- Clock_error clock;
- Utimes_error utimes;
- Wait4_error wait4;
- Kill_error kill;
- Fork_error fork;
-
- } error;
-
- union {
-
- SYSIO_DECL(write, { int fd; size_t count; Chunk chunk; },
- { size_t count; });
-
- SYSIO_DECL(stat, { Path path; }, { Stat st; });
-
- SYSIO_DECL(symlink, { Path oldpath; Path newpath; }, { });
-
- SYSIO_DECL(fstat, { int fd; }, { Stat st; });
-
- SYSIO_DECL(ftruncate, { int fd; off_t length; }, { });
-
- SYSIO_DECL(fcntl, { int fd; long long_arg; Fcntl_cmd cmd; },
- { int result; });
-
- SYSIO_DECL(open, { Path path; int mode; }, { int fd; });
-
- SYSIO_DECL(close, { int fd; }, { });
-
- SYSIO_DECL(ioctl, : Ioctl_in { int fd; }, : Ioctl_out { });
-
- SYSIO_DECL(lseek, { int fd; off_t offset; Lseek_whence whence; },
- { off_t offset; });
-
- SYSIO_DECL(dirent, { int fd; }, { Dirent entry; });
-
- SYSIO_DECL(read, { int fd; size_t count; },
- { Chunk chunk; size_t count; });
-
- SYSIO_DECL(readlink, { Path path; size_t bufsiz; },
- { Chunk chunk; size_t count; });
-
- SYSIO_DECL(execve, { Path filename; Args args; Env env; }, { });
-
- SYSIO_DECL(select, { Select_fds fds; Select_timeout timeout; },
- { Select_fds fds; });
-
- SYSIO_DECL(fork, { addr_t ip; addr_t sp;
- addr_t parent_cap_addr; },
- { int pid; });
-
- SYSIO_DECL(getpid, { }, { int pid; });
-
- SYSIO_DECL(wait4, { int pid; bool nohang; },
- { int pid; int status; });
- SYSIO_DECL(pipe, { }, { int fd[2]; });
-
- SYSIO_DECL(dup2, { int fd; int to_fd; }, { int fd; });
-
- SYSIO_DECL(unlink, { Path path; }, { });
-
- SYSIO_DECL(rename, { Path from_path; Path to_path; }, { });
-
- SYSIO_DECL(mkdir, { Path path; int mode; }, { });
-
- SYSIO_DECL(socket, { int domain; int type; int protocol; },
- { int fd; });
-
- /* XXX for now abuse Chunk for passing optval */
- SYSIO_DECL(getsockopt, { int fd; int level; int optname; Chunk optval;
- socklen_t optlen; }, { int result; });
-
- SYSIO_DECL(setsockopt, { int fd; int level;
- int optname; Chunk optval;
- socklen_t optlen; }, { });
-
- SYSIO_DECL(accept, { int fd; struct sockaddr addr; socklen_t addrlen; },
- { int fd; });
-
- SYSIO_DECL(bind, { int fd; struct sockaddr addr;
- socklen_t addrlen; }, { int result; });
-
- SYSIO_DECL(getpeername, { int fd; struct sockaddr addr;
- socklen_t addrlen; }, { });
-
- SYSIO_DECL(listen, { int fd; int type; int backlog; },
- { int result; });
-
- SYSIO_DECL(send, { int fd; Chunk buf; size_t len; int flags; },
- { ssize_t len; });
-
- SYSIO_DECL(sendto, { int fd; Chunk buf; size_t len; int flags;
- struct sockaddr dest_addr; socklen_t addrlen; },
- { ssize_t len; });
-
- SYSIO_DECL(recv, { int fd; Chunk buf; size_t len; int flags; },
- { size_t len; });
-
- SYSIO_DECL(recvfrom, { int fd; Chunk buf; size_t len; int flags;
- struct sockaddr src_addr; socklen_t addrlen; },
- { size_t len; });
-
- SYSIO_DECL(shutdown, { int fd; int how; }, { });
-
- SYSIO_DECL(connect, { int fd; struct sockaddr addr; socklen_t addrlen; },
- { int result; });
-
- SYSIO_DECL(userinfo, { int request; Uid uid; },
- { User name; Uid uid; Uid gid; Shell shell;
- Home home; });
-
- SYSIO_DECL(gettimeofday, { }, { unsigned long sec; unsigned int usec; });
-
- SYSIO_DECL(clock_gettime, { Clock_Id clock_id; },
- { unsigned long sec; unsigned long nsec; });
-
- SYSIO_DECL(utimes, { Path path; unsigned long sec; unsigned long usec; },
- { });
-
- SYSIO_DECL(sync, { }, { });
-
- SYSIO_DECL(kill, { int pid; Signal sig; }, { });
-
- SYSIO_DECL(getdtablesize, { }, { int n; });
- };
-};
-
-#undef SYSIO_DECL
-
-#endif /* _INCLUDE__NOUX_SESSION__SYSIO_H_ */
diff --git a/repos/ports/lib/mk/libc_noux.mk b/repos/ports/lib/mk/libc_noux.mk
deleted file mode 100644
index 4f385ce5e8..0000000000
--- a/repos/ports/lib/mk/libc_noux.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-SRC_CC = plugin.cc
-
-LIBS += libc
-
-REP_INC_DIR += src/lib/libc
-
-vpath %.cc $(REP_DIR)/src/lib/libc_noux
-
-SHARED_LIB = yes
-
-CC_CXX_WARN_STRICT =
diff --git a/repos/ports/lib/symbols/libc_noux b/repos/ports/lib/symbols/libc_noux
deleted file mode 100644
index 5ab5212c4d..0000000000
--- a/repos/ports/lib/symbols/libc_noux
+++ /dev/null
@@ -1,35 +0,0 @@
-_Z14init_libc_nouxv T
-_Z15noux_connectionv T
-_Z4nouxv T
-_Z5sysiov T
-_ZN4Libc10vfs_configEv T
-_ZN4Libc6configEv T
-_sigaction T
-_sigprocmask T
-_wait4 T
-chmod T
-clock_gettime T
-endpwent T
-fork T
-fork_trampoline T
-getdtablesize T
-getegid T
-geteuid T
-getgid T
-getpid T
-getppid T
-getpwuid T
-getrlimit T
-getrusage T
-gettimeofday T
-getuid T
-kill T
-nanosleep T
-sbrk T
-select T
-sigaction T
-sigprocmask T
-sleep T
-sync T
-utimes T
-vfork T
diff --git a/repos/ports/recipes/api/noux/content.mk b/repos/ports/recipes/api/noux/content.mk
index 30efcec87d..4aab8870fe 100644
--- a/repos/ports/recipes/api/noux/content.mk
+++ b/repos/ports/recipes/api/noux/content.mk
@@ -1,4 +1,4 @@
-MIRROR_FROM_REP_DIR := lib/symbols/libc_noux mk/noux.mk mk/gnu_build.mk
+MIRROR_FROM_REP_DIR := mk/noux.mk mk/gnu_build.mk
content:$(MIRROR_FROM_REP_DIR) LICENSE
diff --git a/repos/ports/recipes/api/noux_session/content.mk b/repos/ports/recipes/api/noux_session/content.mk
deleted file mode 100644
index 97581bfa94..0000000000
--- a/repos/ports/recipes/api/noux_session/content.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-MIRRORED_FROM_REP_DIR := include/noux_session
-include $(GENODE_DIR)/repos/os/recipes/api/session.inc
diff --git a/repos/ports/recipes/api/noux_session/hash b/repos/ports/recipes/api/noux_session/hash
deleted file mode 100644
index b943ee6cc5..0000000000
--- a/repos/ports/recipes/api/noux_session/hash
+++ /dev/null
@@ -1 +0,0 @@
-2020-03-25 5b839717ad8acc5742ac2e7f78f2c50d3d77b1ca
diff --git a/repos/ports/recipes/pkg/system_shell/archives b/repos/ports/recipes/pkg/system_shell/archives
index f1f1e86fc0..60d547d8f2 100644
--- a/repos/ports/recipes/pkg/system_shell/archives
+++ b/repos/ports/recipes/pkg/system_shell/archives
@@ -1,5 +1,4 @@
_/raw/system_shell
-_/src/noux
_/src/bash-minimal
_/src/vim-minimal
_/src/coreutils-minimal
diff --git a/repos/ports/recipes/src/noux/content.mk b/repos/ports/recipes/src/noux/content.mk
deleted file mode 100644
index d710e432d7..0000000000
--- a/repos/ports/recipes/src/noux/content.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-MIRROR_FROM_REP_DIR := src/noux src/lib/libc_noux lib/mk/libc_noux.mk
-
-content: $(MIRROR_FROM_REP_DIR)
-
-$(MIRROR_FROM_REP_DIR):
- $(mirror_from_rep_dir)
-
-MIRROR_FROM_LIBPORTS := include/libc-plugin \
- src/lib/libc/internal/mem_alloc.h \
- src/lib/libc/internal/types.h \
- src/lib/libc/internal/legacy.h
-
-content: $(MIRROR_FROM_LIBPORTS)
-
-$(MIRROR_FROM_LIBPORTS):
- mkdir -p $(dir $@)
- cp -r $(GENODE_DIR)/repos/libports/$@ $@
-
-MIRROR_FROM_OS := include/init/child_policy.h
-
-content: $(MIRROR_FROM_OS)
-
-$(MIRROR_FROM_OS):
- mkdir -p $(dir $@)
- cp -r $(GENODE_DIR)/repos/os/$@ $@
-
-content: LICENSE
-
-LICENSE:
- cp $(GENODE_DIR)/LICENSE $@
-
diff --git a/repos/ports/recipes/src/noux/hash b/repos/ports/recipes/src/noux/hash
deleted file mode 100644
index 93dd6ba7bb..0000000000
--- a/repos/ports/recipes/src/noux/hash
+++ /dev/null
@@ -1 +0,0 @@
-2020-03-25 d13b8d86250ac0f22c9ea71fc4cfce2759aeba18
diff --git a/repos/ports/recipes/src/noux/used_apis b/repos/ports/recipes/src/noux/used_apis
deleted file mode 100644
index ddb9ebeff1..0000000000
--- a/repos/ports/recipes/src/noux/used_apis
+++ /dev/null
@@ -1,10 +0,0 @@
-base
-os
-vfs
-libc
-noux
-noux_session
-terminal_session
-timer_session
-posix
-rtc_session
diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc
deleted file mode 100644
index a2d6b7b602..0000000000
--- a/repos/ports/src/lib/libc_noux/plugin.cc
+++ /dev/null
@@ -1,2434 +0,0 @@
-/*
- * \brief Noux libc plugin
- * \author Norman Feske
- * \date 2011-02-14
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* noux includes */
-#include
-#include
-
-/* libc plugin includes */
-#include
-#include
-
-/* libc component includes */
-#include
-
-/* libc includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/**
- * There is a off_t typedef clash between sys/socket.h
- * and base/stdint.h. We define the macro here to circumvent
- * this issue.
- */
-#undef DIOCGMEDIASIZE
-#define DIOCGMEDIASIZE _IOR('d', 129, int64_t)
-
-
-/* libc-internal includes */
-#include
-#include
-
-
-using Genode::log;
-using Genode::error;
-using Genode::warning;
-using Genode::Hex;
-
-
-enum { verbose = false };
-enum { verbose_signals = false };
-
-
-/*
- * Customize libc VFS
- */
-namespace Libc {
-
- /*
- * Override the weak function interface of the libc and VFS plugin as Noux
- * programs do not obtain such configuration via Genode's config mechanism.
- */
- Genode::Xml_node config() { return Xml_node(""); }
- Genode::Xml_node vfs_config() { return Xml_node(""); }
-
- /*
- * Enhance main-thread stack
- *
- * This is done because we ran into a stack overflow while compiling
- * Genodes core with GCC in Noux.
- */
- enum { STACK_SIZE = 64UL * 1024 * sizeof(Genode::addr_t) };
- Genode::size_t Component::stack_size() { return STACK_SIZE; }
-}
-
-
-
-class Noux_connection
-{
- private:
-
- Genode::Env &_env;
-
- Noux::Connection _connection;
-
- Genode::Attached_dataspace _sysio_ds { _env.rm(), _connection.sysio_dataspace() };
-
- public:
-
- Noux_connection(Genode::Env &env) : _env(env), _connection(env) { }
-
- /**
- * Return the capability of the local stack-area region map
- *
- * \param ptr some address within the stack-area
- */
- Genode::Capability stack_area_region_map(void * const ptr)
- {
- return _connection.lookup_region_map((Genode::addr_t)ptr);
- }
-
- Noux::Session *session() { return &_connection; }
- Noux::Sysio *sysio() { return _sysio_ds.local_addr(); }
-
- void reconnect()
- {
- using namespace Genode;
-
- /*
- * Release Id_space::Element of the local ID space.
- */
- _connection.discard_session_id();
-
- /*
- * Obtain new noux connection. Note that we cannot reconstruct
- * the connection via a 'Reconstructible' because this would
- * result in an inconsistent referernce count when attempting
- * to destruct the session capability in the just-cleared
- * capability space.
- */
- construct_at(this, _env);
- }
-};
-
-
-/*
- * Defined by Libc::Plugin::init
- */
-static Genode::Env *_env_ptr = nullptr;
-
-Noux_connection *noux_connection()
-{
- if (!_env_ptr) {
- Genode::error("missing call of 'Libc::Plugin::init'");
- return nullptr;
- }
-
- static Noux_connection inst(*_env_ptr);
- return &inst;
-}
-
-
-Noux::Session *noux() { return noux_connection()->session(); }
-Noux::Sysio *sysio() { return noux_connection()->sysio(); }
-
-
-/*
- * Array of signal handlers, initialized with 0 (SIG_DFL)
- * TODO: preserve ignored signals across 'execve()'
- */
-static struct sigaction signal_action[NSIG+1];
-
-/*
- * Signal mask functionality is not fully implemented yet.
- * TODO: - actually block delivery of to be blocked signals
- * - preserve signal mask across 'execve()'
- */
-static sigset_t signal_mask;
-
-
-static bool noux_syscall(Noux::Session::Syscall opcode)
-{
- /*
- * Signal handlers might do syscalls themselves, so the 'sysio' object
- * needs to be saved before and restored after calling the signal handler.
- * There is only one global 'saved_sysio' buffer as signals are not checked
- * in nested calls of 'noux_syscall' from signal handlers.
- */
- static Noux::Sysio saved_sysio;
-
- bool ret = noux()->syscall(opcode);
-
- static bool in_sigh = false; /* true if called from signal handler */
-
- if (in_sigh)
- return ret;
-
- /* handle signals */
- while (!sysio()->pending_signals.empty()) {
- in_sigh = true;
- Noux::Sysio::Signal signal = sysio()->pending_signals.get();
- if (verbose_signals)
- log(__func__, ": received signal ", (int)signal);
- if (signal_action[signal].sa_flags & SA_SIGINFO) {
- memcpy(&saved_sysio, sysio(), sizeof(Noux::Sysio));
- /* TODO: pass siginfo_t struct */
- signal_action[signal].sa_sigaction(signal, 0, 0);
- memcpy(sysio(), &saved_sysio, sizeof(Noux::Sysio));
- } else {
- if (signal_action[signal].sa_handler == SIG_DFL) {
- switch (signal) {
- case SIGCHLD:
- case SIGWINCH:
- /* ignore */
- break;
- default:
- /* terminate the process */
- exit((signal << 8) | EXIT_FAILURE);
- }
- } else if (signal_action[signal].sa_handler == SIG_IGN) {
- /* do nothing */
- } else {
- memcpy(&saved_sysio, sysio(), sizeof(Noux::Sysio));
- signal_action[signal].sa_handler(signal);
- memcpy(sysio(), &saved_sysio, sizeof(Noux::Sysio));
- }
- }
- }
- in_sigh = false;
-
- return ret;
-}
-
-
-enum { FS_BLOCK_SIZE = 4096 };
-
-
-/***********************************************
- ** Overrides of libc default implementations **
- ***********************************************/
-
-/**
- * User information related functions
- */
-extern "C" struct passwd *getpwuid(uid_t uid)
-{
- static char name[Noux::Sysio::MAX_USERNAME_LEN];
- static char shell[Noux::Sysio::MAX_SHELL_LEN];
- static char home[Noux::Sysio::MAX_HOME_LEN];
-
- static char *empty = strdup("");
-
- static struct passwd pw = {
- /* .pw_name = */ name,
- /* .pw_passwd = */ empty,
- /* .pw_uid = */ 0,
- /* .pw_gid = */ 0,
- /* .pw_change = */ 0,
- /* .pw_class = */ empty,
- /* .pw_gecos = */ empty,
- /* .pw_dir = */ home,
- /* .pw_shell = */ shell,
- /* .pw_expire = */ 0,
- /* .pw_fields = */ 0
- };
-
- sysio()->userinfo_in.uid = uid;
- sysio()->userinfo_in.request = Noux::Sysio::USERINFO_GET_ALL;
-
- if (!noux_syscall(Noux::Session::SYSCALL_USERINFO)) {
- return (struct passwd *)0;
- }
-
- /* SYSCALL_USERINFO assures that strings are always '\0' terminated */
- Genode::memcpy(name, sysio()->userinfo_out.name, sizeof (sysio()->userinfo_out.name));
- Genode::memcpy(home, sysio()->userinfo_out.home, sizeof (sysio()->userinfo_out.home));
- Genode::memcpy(shell, sysio()->userinfo_out.shell, sizeof (sysio()->userinfo_out.shell));
-
- pw.pw_uid = sysio()->userinfo_out.uid;
- pw.pw_gid = sysio()->userinfo_out.gid;
-
- return &pw;
-}
-
-
-extern "C" int getdtablesize()
-{
- if (!noux_syscall(Noux::Session::SYSCALL_GETDTABLESIZE)) {
- warning("getdtablesize syscall failed");
- errno = ENOSYS;
- return -1;
- }
-
- int n = sysio()->getdtablesize_out.n;
- return n;
-}
-
-
-extern "C" uid_t getgid()
-{
- sysio()->userinfo_in.request = Noux::Sysio::USERINFO_GET_GID;
-
- if (!noux_syscall(Noux::Session::SYSCALL_USERINFO))
- return 0;
-
- uid_t gid = sysio()->userinfo_out.gid;
- return gid;
-}
-
-
-extern "C" uid_t getegid()
-{
- return getgid();
-}
-
-
-extern "C" uid_t getuid()
-{
- sysio()->userinfo_in.request = Noux::Sysio::USERINFO_GET_UID;
-
- if (!noux_syscall(Noux::Session::SYSCALL_USERINFO))
- return 0;
-
- uid_t uid = sysio()->userinfo_out.uid;
-
- return uid;
-}
-
-
-extern "C" uid_t geteuid()
-{
- return getuid();
-}
-
-
-void *sbrk(intptr_t increment)
-{
- if (verbose)
- warning(__func__, " not implemented ", (long int)increment);
- errno = ENOMEM;
- return reinterpret_cast(-1);
-}
-
-
-extern "C" int getrlimit(int resource, struct rlimit *rlim)
-{
- switch (resource) {
- case RLIMIT_STACK:
- {
- using namespace Genode;
-
- Thread * me = Thread::myself();
-
- if (!me)
- break;
-
- addr_t top = reinterpret_cast(me->stack_top());
- addr_t cur = reinterpret_cast(me->stack_base());
-
- rlim->rlim_cur = rlim->rlim_max = top - cur;
- return 0;
- }
- case RLIMIT_AS:
- #ifdef __x86_64__
- rlim->rlim_cur = rlim->rlim_max = 0x800000000000UL;
- #else
- rlim->rlim_cur = rlim->rlim_max = 0xc0000000UL;
- #endif
- return 0;
- case RLIMIT_RSS:
- rlim->rlim_cur = rlim->rlim_max = _env_ptr->pd().ram_quota().value;
- return 0;
- case RLIMIT_NPROC:
- case RLIMIT_NOFILE:
- rlim->rlim_cur = rlim->rlim_max = RLIM_INFINITY;
- return 0;
- }
- errno = ENOSYS;
- return -1;
-}
-
-
-/**
- * Utility to copy-out syscall results to buf struct
- *
- * Code shared between 'stat' and 'fstat'.
- */
-static void _sysio_to_stat_struct(Noux::Sysio const *sysio, struct stat *buf)
-{
- unsigned const readable_bits = S_IRUSR,
- writeable_bits = S_IWUSR,
- executable_bits = S_IXUSR;
-
- auto type = [] (Vfs::Node_type type)
- {
- switch (type) {
- case Vfs::Node_type::DIRECTORY: return S_IFDIR;
- case Vfs::Node_type::CONTINUOUS_FILE: return S_IFREG;
- case Vfs::Node_type::TRANSACTIONAL_FILE: return S_IFSOCK;
- case Vfs::Node_type::SYMLINK: return S_IFLNK;
- }
- return 0;
- };
-
- Vfs::Directory_service::Stat const &src = sysio->stat_out.st;
-
- *buf = { };
-
- buf->st_uid = 0;
- buf->st_gid = 0;
- buf->st_mode = (src.rwx.readable ? readable_bits : 0)
- | (src.rwx.writeable ? writeable_bits : 0)
- | (src.rwx.executable ? executable_bits : 0)
- | type(src.type);
- buf->st_size = src.size;
- buf->st_blksize = FS_BLOCK_SIZE;
- buf->st_blocks = (src.size + FS_BLOCK_SIZE - 1) / FS_BLOCK_SIZE;
- buf->st_ino = src.inode;
- buf->st_dev = src.device;
-
- if (src.modification_time.value != Vfs::Timestamp::INVALID)
- buf->st_mtime = src.modification_time.value;
-}
-
-
-static bool serialize_string_array(char const * const * array, char *dst, Genode::size_t dst_len)
-{
- for (unsigned i = 0; array[i]; i++)
- {
- Genode::size_t const curr_len = Genode::strlen(array[i]) + 1;
- if (curr_len + 1 >= dst_len)
- return false;
-
- Genode::strncpy(dst, array[i], dst_len);
- dst += curr_len;
- dst_len -= curr_len;
- }
-
- dst[0] = 0;
- return true;
-}
-
-
-/**
- * Return number of marhalled file descriptors into select argument buffer
- *
- * \return number of marshalled file descriptors, this value is guaranteed to
- * not exceed the 'dst_fds_len' argument
- */
-static size_t marshal_fds(fd_set *src_fds, int nfds,
- int *dst_fds, size_t dst_fds_len)
-{
- if (!src_fds) return 0;
-
- size_t num_fds = 0;
-
- for (int fd = 0; (fd < nfds) && (num_fds < dst_fds_len); fd++)
- if (FD_ISSET(fd, src_fds))
- dst_fds[num_fds++] = fd;
-
- return num_fds;
-}
-
-
-/**
- * Unmarshal result of select syscall into fd set
- */
-static void unmarshal_fds(int nfds, int *src_fds, size_t src_fds_len, fd_set *dst_fds)
-{
- if (!dst_fds) return;
-
- /**
- * Calling FD_ZERO will not work because it will try to reset sizeof (fd_set)
- * which is typically 128 bytes but dst_fds might by even less bytes large if
- * it was allocated dynamically. So we will reset the fd_set manually which
- * will work fine as long as we are using FreeBSDs libc - another libc however
- * might use a different struct.
- *
- * Note: The fds are actually stored in a bit-array. So we need to calculate
- * how many array entries we have to reset. sizeof (fd_mask) will return the
- * size of one entry in bytes.
- */
- int _ = nfds / (sizeof (fd_mask) * 8) + 1;
- for (int i = 0; i < _; i++)
- dst_fds->__fds_bits[i] = 0;
-
- for (size_t i = 0; i < src_fds_len; i++)
- FD_SET(src_fds[i], dst_fds);
-}
-
-
-extern "C" int select(int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
-{
-
- /*
- * Marshal file descriptor into sysio page
- */
- Noux::Sysio::Select_fds &in_fds = sysio()->select_in.fds;
-
- int *dst = in_fds.array;
- size_t dst_len = Noux::Sysio::Select_fds::MAX_FDS;
-
- /**
- * These variables are used in max_fds_exceeded() calculation, so
- * they need to be proper initialized.
- */
- in_fds.num_rd = 0;
- in_fds.num_wr = 0;
- in_fds.num_ex = 0;
-
- if (readfds != NULL) {
- in_fds.num_rd = marshal_fds(readfds, nfds, dst, dst_len);
-
- dst += in_fds.num_rd;
- dst_len -= in_fds.num_rd;
- }
-
- if (writefds != NULL) {
- in_fds.num_wr = marshal_fds(writefds, nfds, dst, dst_len);
-
- dst += in_fds.num_wr;
- dst_len -= in_fds.num_wr;
- }
-
- if (exceptfds != NULL) {
- in_fds.num_ex = marshal_fds(exceptfds, nfds, dst, dst_len);
- }
-
- if (in_fds.max_fds_exceeded()) {
- errno = ENOMEM;
- return -1;
- }
-
- /*
- * Marshal timeout
- */
- if (timeout) {
- sysio()->select_in.timeout.sec = timeout->tv_sec;
- sysio()->select_in.timeout.usec = timeout->tv_usec;
- } else {
- sysio()->select_in.timeout.set_infinite();
- }
-
- /*
- * Perform syscall
- */
- if (!noux_syscall(Noux::Session::SYSCALL_SELECT)) {
- switch (sysio()->error.select) {
- case Noux::Sysio::SELECT_ERR_INTERRUPT: errno = EINTR; break;
- }
- return -1;
- }
-
- /*
- * Unmarshal file selectors reported by the select syscall
- */
- Noux::Sysio::Select_fds &out_fds = sysio()->select_out.fds;
-
- int *src = out_fds.array;
- int total_fds = 0;
-
- if (readfds != NULL) {
- unmarshal_fds(nfds, src, out_fds.num_rd, readfds);
- src += out_fds.num_rd;
- total_fds += out_fds.num_rd;
- }
-
- if (writefds != NULL) {
- unmarshal_fds(nfds, src, out_fds.num_wr, writefds);
- src += out_fds.num_wr;
- total_fds += out_fds.num_wr;
- }
-
- if (exceptfds != NULL) {
- unmarshal_fds(nfds, src, out_fds.num_ex, exceptfds);
- /* exceptfds are currently ignored */
- }
-
- return total_fds;
-}
-
-
-#include
-
-
-static void * in_stack_area;
-static jmp_buf fork_jmp_buf;
-static Genode::Capability::Raw new_parent;
-
-extern "C" void stdout_reconnect(Genode::Parent &); /* provided by 'default_log.cc' */
-
-
-/*
- * The new process created via fork will start its execution here.
- */
-extern "C" void fork_trampoline()
-{
- /* reinitialize environment */
- using namespace Genode;
- _env_ptr->reinit(new_parent);
-
- /* reinitialize standard-output connection */
- stdout_reconnect(_env_ptr->parent());
-
- /* reinitialize noux connection */
- noux_connection()->reconnect();
-
- /* reinitialize main-thread object which implies reinit of stack area */
- auto stack_area_rm = noux_connection()->stack_area_region_map(in_stack_area);
- _env_ptr->reinit_main_thread(stack_area_rm);
-
- /* apply processor state that the forker had when he did the fork */
- longjmp(fork_jmp_buf, 1);
-}
-
-
-static pid_t fork_result;
-
-
-/**
- * Called once the component has left the entrypoint and exited the signal
- * dispatch loop.
- *
- * This function is called from the context of the initial thread.
- */
-static void suspended_callback()
-{
- /* stack used for executing 'fork_trampoline' */
- enum { STACK_SIZE = 8 * 1024 };
- static long stack[STACK_SIZE];
-
- if (setjmp(fork_jmp_buf)) {
-
- /*
- * We got here via longjmp from 'fork_trampoline'.
- */
- fork_result = 0;
-
- } else {
-
- /*
- * save the current stack address used for re-initializing
- * the stack area during process bootstrap
- */
- int dummy;
- in_stack_area = &dummy;
-
- /* got here during the normal control flow of the fork call */
- sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline);
- sysio()->fork_in.sp = Abi::stack_align((Genode::addr_t)&stack[STACK_SIZE]);
- sysio()->fork_in.parent_cap_addr = (Genode::addr_t)(&new_parent);
-
- if (!noux_syscall(Noux::Session::SYSCALL_FORK)) {
- error("fork error ", (int)sysio()->error.general);
- switch (sysio()->error.fork) {
- case Noux::Sysio::FORK_NOMEM: errno = ENOMEM; break;
- default: errno = EAGAIN;
- }
- fork_result = -1;
- return;
- }
-
- fork_result = sysio()->fork_out.pid;
- }
-}
-
-
-namespace Libc { void schedule_suspend(void (*suspended) ()); }
-
-
-extern "C" pid_t fork(void)
-{
- Libc::schedule_suspend(suspended_callback);
-
- return fork_result;
-}
-
-
-extern "C" pid_t vfork(void) { return fork(); }
-
-
-extern "C" pid_t getpid(void)
-{
- noux_syscall(Noux::Session::SYSCALL_GETPID);
- return sysio()->getpid_out.pid;
-}
-
-
-extern "C" pid_t getppid(void) { return getpid(); }
-
-
-extern "C" int chmod(char const *path, mode_t mode)
-{
- if (verbose)
- warning(__func__, ": chmod '", path, "' to ", Hex(mode), " not implemented");
- return 0;
-}
-
-
-extern "C" pid_t wait4(pid_t pid, int *status, int options,
- struct rusage *rusage)
-{
- sysio()->wait4_in.pid = pid;
- sysio()->wait4_in.nohang = !!(options & WNOHANG);
- if (!noux_syscall(Noux::Session::SYSCALL_WAIT4)) {
- switch (sysio()->error.wait4) {
- case Noux::Sysio::WAIT4_ERR_INTERRUPT: errno = EINTR; break;
- }
- return -1;
- }
-
- /*
- * The libc expects status information in bits 0..6 and the exit value
- * in bits 8..15 (according to 'wait.h').
- */
- if (status)
- *status = ((sysio()->wait4_out.status >> 8) & 0177) |
- ((sysio()->wait4_out.status & 0xff) << 8);
-
- return sysio()->wait4_out.pid;
-}
-
-
-extern "C" __attribute__((alias("wait4")))
-pid_t _wait4(pid_t, int *, int, struct rusage *);
-
-
-extern "C" __attribute__((alias("wait4")))
-pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
-
-
-extern "C" pid_t waitpid(pid_t pid, int *istat, int options)
-{
- return wait4(pid, istat, options, NULL);
-}
-
-
-extern "C" int execve(char const *filename, char *const argv[],
- char *const envp[])
-{
- if (verbose) {
- log(__func__, ": filename=", filename);
-
- for (int i = 0; argv[i]; i++)
- log(__func__, "argv[", i, "]='", Genode::Cstring(argv[i]), "'");
-
- for (int i = 0; envp[i]; i++)
- log(__func__, "envp[", i, "]='", Genode::Cstring(envp[i]), "'");
- }
-
- Libc::Absolute_path resolved_path;
- try {
- Libc::resolve_symlinks(filename, resolved_path);
- } catch (Libc::Symlink_resolve_error) {
- return -1;
- }
-
- Genode::strncpy(sysio()->execve_in.filename, resolved_path.string(),
- sizeof(sysio()->execve_in.filename));
- if (!serialize_string_array(argv, sysio()->execve_in.args,
- sizeof(sysio()->execve_in.args))) {
- error("execve: argument buffer exceeded");
- errno = E2BIG;
- return -1;
- }
-
- /* communicate the current working directory as environment variable */
-
- size_t noux_cwd_len = Genode::snprintf(sysio()->execve_in.env,
- sizeof(sysio()->execve_in.env),
- "NOUX_CWD=");
-
- if (!getcwd(&(sysio()->execve_in.env[noux_cwd_len]),
- sizeof(sysio()->execve_in.env) - noux_cwd_len)) {
- error("execve: environment buffer exceeded");
- errno = E2BIG;
- return -1;
- }
-
- noux_cwd_len = strlen(sysio()->execve_in.env) + 1;
-
- if (!serialize_string_array(envp, &(sysio()->execve_in.env[noux_cwd_len]),
- sizeof(sysio()->execve_in.env) - noux_cwd_len)) {
- error("execve: environment buffer exceeded");
- errno = E2BIG;
- return -1;
- }
-
- if (!noux_syscall(Noux::Session::SYSCALL_EXECVE)) {
- warning("exec syscall failed for path \"", filename, "\"");
- switch (sysio()->error.execve) {
- case Noux::Sysio::EXECVE_ERR_NO_ENTRY: errno = ENOENT; break;
- case Noux::Sysio::EXECVE_ERR_NO_MEMORY: errno = ENOMEM; break;
- case Noux::Sysio::EXECVE_ERR_NO_EXEC: errno = ENOEXEC; break;
- case Noux::Sysio::EXECVE_ERR_ACCESS: errno = EACCES; break;
- }
- return -1;
- }
-
- /*
- * In the success case, we never return from execve, the execution is
- * resumed in the new program.
- */
- Genode::sleep_forever();
- return 0;
-}
-
-
-extern "C" int _execve(char const *, char *const[], char *const[]) __attribute__((alias("execve")));
-
-
-int getrusage(int who, struct rusage *usage)
-{
- if (verbose)
- warning(__func__, " not implemented");
-
- errno = ENOSYS;
- return -1;
-}
-
-
-void endpwent(void)
-{
- if (verbose)
- warning(__func__, " not implemented");
-}
-
-
-extern "C" void sync(void)
-{
- noux_syscall(Noux::Session::SYSCALL_SYNC);
-}
-
-
-extern "C" int kill(__pid_t pid, int sig)
-{
- if (verbose_signals)
- log(__func__, ": pid=", pid, ", sig=", sig);
-
- sysio()->kill_in.pid = pid;
- sysio()->kill_in.sig = Noux::Sysio::Signal(sig);
-
- if (!noux_syscall(Noux::Session::SYSCALL_KILL)) {
- switch (sysio()->error.kill) {
- case Noux::Sysio::KILL_ERR_SRCH: errno = ESRCH; break;
- }
- return -1;
- }
-
- return 0;
-}
-
-
-extern "C" int raise(int sig)
-{
- return kill(getpid(), sig);
-}
-
-
-extern "C" int nanosleep(const struct timespec *timeout,
- struct timespec *remainder)
-{
- Noux::Sysio::Select_fds &in_fds = sysio()->select_in.fds;
-
- in_fds.num_rd = 0;
- in_fds.num_wr = 0;
- in_fds.num_ex = 0;
-
- sysio()->select_in.timeout.sec = timeout->tv_sec;
- sysio()->select_in.timeout.usec = timeout->tv_nsec / 1000;
-
- /*
- * Perform syscall
- */
- if (!noux_syscall(Noux::Session::SYSCALL_SELECT)) {
- switch (sysio()->error.select) {
- case Noux::Sysio::SELECT_ERR_INTERRUPT: errno = EINTR; break;
- }
-
- return -1;
- }
-
- if (remainder) {
- remainder->tv_sec = 0;
- remainder->tv_nsec = 0;
- }
-
- return 0;
-}
-
-
-extern "C" unsigned int sleep(unsigned int seconds)
-{
- struct timespec dummy = { Genode::min(seconds, __INT_MAX__), 0 };
-
- /*
- * Always return 0 because our nanosleep() cannot not be interrupted.
- */
- nanosleep(&dummy, 0);
- return 0;
-}
-
-
-/********************
- ** Time functions **
- ********************/
-
-/*
- * The default implementations as provided by the libc rely on a dedicated
- * thread. But on Noux, no thread other than the main thread is allowed. For
- * this reason, we need to override the default implementations here.
- */
-
-extern "C" int clock_gettime(clockid_t clk_id, struct timespec *tp)
-{
- /* we currently only support CLOCK_SECOND */
- switch (clk_id) {
- case CLOCK_SECOND:
- sysio()->clock_gettime_in.clock_id = Noux::Sysio::CLOCK_ID_SECOND;
- break;
- default:
- /* let's save the trip to noux and return directly */
- errno = EINVAL;
- return -1;
- }
-
- if (!noux_syscall(Noux::Session::SYSCALL_CLOCK_GETTIME)) {
- switch (sysio()->error.clock) {
- case Noux::Sysio::CLOCK_ERR_INVALID: errno = EINVAL; break;
- default: errno = 0; break;
- }
-
- return -1;
- }
-
- tp->tv_sec = sysio()->clock_gettime_out.sec;
- tp->tv_nsec = sysio()->clock_gettime_out.nsec;
-
- return 0;
-}
-
-
-extern "C" int gettimeofday(struct timeval *tv, struct timezone *tz)
-{
- if (!noux_syscall(Noux::Session::SYSCALL_GETTIMEOFDAY)) {
- errno = EINVAL;
- return -1;
- }
-
- tv->tv_sec = sysio()->gettimeofday_out.sec;
- tv->tv_usec = sysio()->gettimeofday_out.usec;
-
- return 0;
-}
-
-
-extern "C" int utimes(const char* path, const struct timeval *times)
-{
- char * const dst = sysio()->utimes_in.path;
- size_t const max_len = sizeof(sysio()->utimes_in.path);
- Genode::strncpy(dst, path, max_len);
-
- sysio()->utimes_in.sec = times ? times->tv_sec : 0;
- sysio()->utimes_in.usec = times ? times->tv_usec : 0;
-
- if (!noux_syscall(Noux::Session::SYSCALL_UTIMES)) {
- errno = EINVAL;
- return -1;
- }
-
- return 0;
-}
-
-
-/*********************
- ** Signal handling **
- *********************/
-
-extern "C" int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
-{
- if (oldset)
- *oldset = signal_mask;
-
- if (!set)
- return 0;
-
- switch (how) {
- case SIG_BLOCK:
- for (int sig = 1; sig < NSIG; sig++)
- if (sigismember(set, sig)) {
- if (verbose_signals)
- log(__func__, ": signal ", sig, " requested to get blocked");
- sigaddset(&signal_mask, sig);
- }
- break;
- case SIG_UNBLOCK:
- for (int sig = 1; sig < NSIG; sig++)
- if (sigismember(set, sig)) {
- if (verbose_signals)
- log(__func__, ": signal ", sig, " requested to get unblocked");
- sigdelset(&signal_mask, sig);
- }
- break;
- case SIG_SETMASK:
- if (verbose_signals)
- for (int sig = 1; sig < NSIG; sig++)
- if (sigismember(set, sig))
- log(__func__, ": signal ", sig, " requested to get blocked");
- signal_mask = *set;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
-
- return 0;
-}
-
-
-extern "C" int _sigprocmask(int how, const sigset_t *set, sigset_t *oldset) __attribute__((alias("sigprocmask")));
-
-
-extern "C" int _sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
-{
- if (verbose_signals)
- log("signum=", signum, ", handler=", act ? act->sa_handler : nullptr);
-
- if ((signum < 1) || (signum > NSIG)) {
- errno = EINVAL;
- return -1;
- }
-
- if (oldact)
- *oldact = signal_action[signum];
-
- if (act)
- signal_action[signum] = *act;
-
- return 0;
-}
-
-
-extern "C" int sigaction(int, const struct sigaction *, struct sigaction *) __attribute__((alias("_sigaction")));
-extern "C" int __libc_sigaction(int, const struct sigaction *, struct sigaction *) __attribute__((alias("_sigaction")));
-
-
-/*********************
- ** File operations **
- *********************/
-
-static int noux_fd(Libc::Plugin_context *context)
-{
- /*
- * We use the 'context' pointer only as container for an int value. It is
- * never used as a pointer. To make 64-bit compilers happy, we need to keep
- * the bit width of the cast intact. The upper 32 bit are discarded when
- * leaving the function.
- */
- return (long)context;
-}
-
-
-static Libc::Plugin_context *noux_context(int noux_fd)
-{
- return reinterpret_cast(noux_fd);
-}
-
-
-namespace {
-
- class Plugin : public Libc::Plugin
- {
- private:
-
- /*
- * Override the libc's default VFS plugin
- */
- enum { PLUGIN_PRIORITY = 1 };
-
- public:
-
- /**
- * Constructor
- */
- Plugin() : Libc::Plugin(PLUGIN_PRIORITY) { }
-
- void init(Genode::Env &);
-
- bool supports_access(const char *, int) { return true; }
- bool supports_open(char const *, int) { return true; }
- bool supports_stat(char const *) { return true; }
- bool supports_symlink(char const *, char const*) { return true; }
- bool supports_pipe() { return true; }
- bool supports_unlink(char const *) { return true; }
- bool supports_readlink(const char *, char *, ::size_t) { return true; }
- bool supports_rename(const char *, const char *) { return true; }
- bool supports_rmdir(char const *) { return true; }
- bool supports_mkdir(const char *, mode_t) { return true; }
- bool supports_socket(int, int, int) { return true; }
- bool supports_mmap() { return true; }
-
- int access(char const *, int);
- Libc::File_descriptor *open(char const *, int);
- ssize_t write(Libc::File_descriptor *, const void *, ::size_t);
- int close(Libc::File_descriptor *);
- Libc::File_descriptor *dup(Libc::File_descriptor*);
- int dup2(Libc::File_descriptor *, Libc::File_descriptor *);
- int fstat(Libc::File_descriptor *, struct stat *);
- int fsync(Libc::File_descriptor *);
- int fstatfs(Libc::File_descriptor *, struct statfs *);
- int ftruncate(Libc::File_descriptor *, ::off_t);
- int fcntl(Libc::File_descriptor *, int, long);
- ssize_t getdirentries(Libc::File_descriptor *, char *, ::size_t, ::off_t *);
- ::off_t lseek(Libc::File_descriptor *, ::off_t offset, int whence);
- ssize_t read(Libc::File_descriptor *, void *, ::size_t);
- ssize_t readlink(const char *path, char *buf, ::size_t bufsiz);
- int rename(const char *oldpath, const char *newpath);
- int rmdir(char const *path);
- int stat(char const *, struct stat *);
- int symlink(const char *, const char *);
- int ioctl(Libc::File_descriptor *, int request, char *argp);
- int pipe(Libc::File_descriptor *pipefd[2]);
- int unlink(char const *path);
- int mkdir(const char *path, mode_t mode);
- void *mmap(void *addr, ::size_t length, int prot, int flags,
- Libc::File_descriptor *, ::off_t offset);
- int munmap(void *addr, ::size_t length);
-
- /* Network related functions */
- Libc::File_descriptor *socket(int, int, int);
- Libc::File_descriptor *accept(Libc::File_descriptor *,
- struct sockaddr *, socklen_t *);
- int bind(Libc::File_descriptor *, const struct sockaddr *,
- socklen_t);
- int connect(Libc::File_descriptor *, const struct sockaddr *addr,
- socklen_t addrlen);
- int getpeername(Libc::File_descriptor *, struct sockaddr *,
- socklen_t *);
- int listen(Libc::File_descriptor *, int);
- ssize_t send(Libc::File_descriptor *, const void *, ::size_t,
- int flags);
- ssize_t sendto(Libc::File_descriptor *, const void *, size_t, int,
- const struct sockaddr *, socklen_t);
- ssize_t recv(Libc::File_descriptor *, void *, ::size_t, int);
- ssize_t recvfrom(Libc::File_descriptor *, void *, ::size_t, int,
- struct sockaddr *, socklen_t*);
- int getsockopt(Libc::File_descriptor *, int, int, void *,
- socklen_t *);
- int setsockopt(Libc::File_descriptor *, int , int , const void *,
- socklen_t);
- int shutdown(Libc::File_descriptor *, int how);
- };
-
-
- int Plugin::access(char const *pathname, int mode)
- {
- if (verbose)
- log(__func__, ": access '", pathname, "' (mode=", Hex(mode), ") "
- "called, not implemented");
-
- struct stat stat;
- if (::stat(pathname, &stat) == 0)
- return 0;
-
- errno = ENOENT;
- return -1;
- }
-
-
- int Plugin::stat(char const *path, struct stat *buf)
- {
- if (verbose)
- log(__func__, ": path=", path);
-
- if ((path == NULL) or (buf == NULL)) {
- errno = EFAULT;
- return -1;
- }
-
- Genode::strncpy(sysio()->stat_in.path, path, sizeof(sysio()->stat_in.path));
-
- if (!noux_syscall(Noux::Session::SYSCALL_STAT)) {
- if (verbose)
- warning("stat syscall failed for path \"", path, "\"");
- switch (sysio()->error.stat) {
- case Vfs::Directory_service::STAT_ERR_NO_ENTRY: errno = ENOENT; return -1;
- case Vfs::Directory_service::STAT_ERR_NO_PERM: errno = EACCES; return -1;
- case Vfs::Directory_service::STAT_OK: break; /* never reached */
- }
- }
-
- _sysio_to_stat_struct(sysio(), buf);
- return 0;
- }
-
-
- Libc::File_descriptor *Plugin::open(char const *pathname, int flags)
- {
- if (Genode::strlen(pathname) + 1 > sizeof(sysio()->open_in.path)) {
- log(__func__, ": ENAMETOOLONG");
- errno = ENAMETOOLONG;
- return 0;
- }
-
- bool opened = false;
- while (!opened) {
- Genode::strncpy(sysio()->open_in.path, pathname, sizeof(sysio()->open_in.path));
- sysio()->open_in.mode = flags;
- if (noux_syscall(Noux::Session::SYSCALL_OPEN))
- opened = true;
- else
- switch (sysio()->error.open) {
- case Vfs::Directory_service::OPEN_ERR_UNACCESSIBLE:
- if (!(flags & O_CREAT)) {
- errno = ENOENT;
- return 0;
- }
- /* O_CREAT is set, so try to create the file */
- Genode::strncpy(sysio()->open_in.path, pathname, sizeof(sysio()->open_in.path));
- sysio()->open_in.mode = flags | O_EXCL;
- if (noux_syscall(Noux::Session::SYSCALL_OPEN))
- opened = true;
- else
- switch (sysio()->error.open) {
- case Vfs::Directory_service::OPEN_ERR_EXISTS:
- /* file has been created by someone else in the meantime */
- break;
- case Vfs::Directory_service::OPEN_ERR_NO_PERM:
- errno = EPERM; return 0;
- default:
- errno = ENOENT; return 0;
- }
- break;
- case Vfs::Directory_service::OPEN_ERR_NO_PERM: errno = EPERM; return 0;
- case Vfs::Directory_service::OPEN_ERR_EXISTS: errno = EEXIST; return 0;
- default: errno = ENOENT; return 0;
- }
- }
-
- Libc::Plugin_context *context = noux_context(sysio()->open_out.fd);
- Libc::File_descriptor *fd =
- Libc::file_descriptor_allocator()->alloc(this, context, sysio()->open_out.fd);
- if ((flags & O_TRUNC) && (ftruncate(fd, 0) == -1)) {
- Plugin::close(fd);
- return 0;
- }
- return fd;
- }
-
-
- int Plugin::symlink(const char *oldpath, const char *newpath)
- {
- if (verbose)
- log(__func__, ": ", newpath, " -> ", oldpath);
-
- if ((Genode::strlen(oldpath) + 1 > sizeof(sysio()->symlink_in.oldpath)) ||
- (Genode::strlen(newpath) + 1 > sizeof(sysio()->symlink_in.newpath))) {
- log(__func__, ": ENAMETOOLONG");
- errno = ENAMETOOLONG;
- return 0;
- }
-
- Genode::strncpy(sysio()->symlink_in.oldpath, oldpath, sizeof(sysio()->symlink_in.oldpath));
- Genode::strncpy(sysio()->symlink_in.newpath, newpath, sizeof(sysio()->symlink_in.newpath));
- if (!noux_syscall(Noux::Session::SYSCALL_SYMLINK)) {
- warning("symlink syscall failed for path \"", newpath, "\"");
- switch (sysio()->error.symlink) {
- case Noux::Sysio::SYMLINK_ERR_NO_ENTRY: errno = ENOENT; return -1;
- case Noux::Sysio::SYMLINK_ERR_EXISTS: errno = EEXIST; return -1;
- case Noux::Sysio::SYMLINK_ERR_NO_SPACE: errno = ENOSPC; return -1;
- case Noux::Sysio::SYMLINK_ERR_NO_PERM: errno = EPERM; return -1;
- case Noux::Sysio::SYMLINK_ERR_NAME_TOO_LONG: errno = ENAMETOOLONG; return -1;
- }
- }
-
- return 0;
- }
-
-
- int Plugin::fstatfs(Libc::File_descriptor *, struct statfs *buf)
- {
- buf->f_flags = MNT_UNION;
- return 0;
- }
-
-
- ssize_t Plugin::write(Libc::File_descriptor *fd, const void *buf,
- ::size_t count)
- {
- if (!buf) { errno = EFAULT; return -1; }
-
- /* remember original len for the return value */
- size_t const orig_count = count;
-
- char *src = (char *)buf;
- while (count > 0) {
-
- Genode::size_t curr_count = Genode::min((::size_t)Noux::Sysio::CHUNK_SIZE, count);
-
- sysio()->write_in.fd = noux_fd(fd->context);
- sysio()->write_in.count = curr_count;
- Genode::memcpy(sysio()->write_in.chunk, src, curr_count);
-
- if (!noux_syscall(Noux::Session::SYSCALL_WRITE)) {
- switch (sysio()->error.write) {
- case Vfs::File_io_service::WRITE_ERR_AGAIN: errno = EAGAIN; break;
- case Vfs::File_io_service::WRITE_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
- case Vfs::File_io_service::WRITE_ERR_INVALID: errno = EINVAL; break;
- case Vfs::File_io_service::WRITE_ERR_IO: errno = EIO; break;
- case Vfs::File_io_service::WRITE_ERR_INTERRUPT: errno = EINTR; break;
- default:
- if (sysio()->error.general == Vfs::Directory_service::ERR_FD_INVALID)
- errno = EBADF;
- else
- errno = 0;
- break;
- }
-
- /* try again */
- bool const retry = (errno == EINTR
- || errno == EAGAIN
- || errno == EWOULDBLOCK);
- if (errno && retry)
- continue;
-
- /* leave writing loop on error */
- if (errno)
- break;
- }
-
- count -= sysio()->write_out.count;
- src += sysio()->write_out.count;
- }
- return orig_count - count;
- }
-
-
- ssize_t Plugin::read(Libc::File_descriptor *fd, void *buf, ::size_t count)
- {
- if (!buf) { errno = EFAULT; return -1; }
-
- Genode::size_t sum_read_count = 0;
-
- while (count > 0) {
-
- Genode::size_t curr_count =
- Genode::min(count, sizeof(sysio()->read_out.chunk));
-
- sysio()->read_in.fd = noux_fd(fd->context);
- sysio()->read_in.count = curr_count;
-
- if (!noux_syscall(Noux::Session::SYSCALL_READ)) {
-
- switch (sysio()->error.read) {
- case Vfs::File_io_service::READ_ERR_AGAIN: errno = EAGAIN; break;
- case Vfs::File_io_service::READ_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
- case Vfs::File_io_service::READ_ERR_INVALID: errno = EINVAL; break;
- case Vfs::File_io_service::READ_ERR_IO: errno = EIO; break;
- case Vfs::File_io_service::READ_ERR_INTERRUPT: errno = EINTR; break;
- default:
- if (sysio()->error.general == Vfs::Directory_service::ERR_FD_INVALID)
- errno = EBADF;
- else
- errno = 0;
- break;
- }
-
- /* try again */
- bool const retry = (errno == EINTR
- || errno == EAGAIN
- || errno == EWOULDBLOCK);
- if (errno && retry)
- continue;
-
- return -1;
- }
-
- Genode::memcpy((char*)buf + sum_read_count,
- sysio()->read_out.chunk,
- sysio()->read_out.count);
-
- sum_read_count += sysio()->read_out.count;
-
- if (sysio()->read_out.count < curr_count)
- break; /* end of file */
-
- if (sysio()->read_out.count <= count)
- count -= sysio()->read_out.count;
- else
- break; /* should not happen */
- }
-
- return sum_read_count;
- }
-
-
- int Plugin::close(Libc::File_descriptor *fd)
- {
- sysio()->close_in.fd = noux_fd(fd->context);
- if (!noux_syscall(Noux::Session::SYSCALL_CLOSE)) {
- error("close error");
- /* XXX set errno */
- return -1;
- }
- Libc::file_descriptor_allocator()->free(fd);
- return 0;
- }
-
-
- int Plugin::ioctl(Libc::File_descriptor *fd, int request, char *argp)
- {
- /*
- * Marshal ioctl arguments
- */
- sysio()->ioctl_in.fd = noux_fd(fd->context);
- sysio()->ioctl_in.request = Vfs::File_io_service::IOCTL_OP_UNDEFINED;
-
- switch (request) {
-
- case TIOCGWINSZ:
- sysio()->ioctl_in.request = Vfs::File_io_service::IOCTL_OP_TIOCGWINSZ;
- break;
-
- case TIOCGETA:
- {
- if (verbose)
- log(__func__, ": TIOCGETA - argp=", (void *)argp);
- ::termios *termios = (::termios *)argp;
-
- termios->c_iflag = 0;
- termios->c_oflag = 0;
- termios->c_cflag = 0;
- /*
- * Set 'ECHO' flag, needed by libreadline. Otherwise, echoing
- * user input doesn't work in bash.
- */
- termios->c_lflag = ECHO;
- memset(termios->c_cc, _POSIX_VDISABLE, sizeof(termios->c_cc));
- termios->c_ispeed = 0;
- termios->c_ospeed = 0;
-
- return 0;
- }
-
- break;
-
- case TIOCSETAF:
- {
- sysio()->ioctl_in.request = Vfs::File_io_service::IOCTL_OP_TIOCSETAF;
-
- ::termios *termios = (::termios *)argp;
-
- /**
- * For now only enabling/disabling of ECHO is supported
- */
- if (termios->c_lflag & (ECHO | ECHONL)) {
- sysio()->ioctl_in.argp = (Vfs::File_io_service::IOCTL_VAL_ECHO |
- Vfs::File_io_service::IOCTL_VAL_ECHONL);
- }
- else {
- sysio()->ioctl_in.argp = Vfs::File_io_service::IOCTL_VAL_NULL;
- }
-
- break;
- }
-
- case TIOCSETAW:
- {
- sysio()->ioctl_in.request = Vfs::File_io_service::IOCTL_OP_TIOCSETAW;
- sysio()->ioctl_in.argp = argp ? *(int*)argp : 0;
-
- break;
- }
-
- case FIONBIO:
- {
- if (verbose)
- log(__func__, ": FIONBIO - *argp=", *argp);
-
- sysio()->ioctl_in.request = Vfs::File_io_service::IOCTL_OP_FIONBIO;
- sysio()->ioctl_in.argp = argp ? *(int*)argp : 0;
-
- break;
- }
-
- case DIOCGMEDIASIZE:
- {
- sysio()->ioctl_in.request = Vfs::File_io_service::IOCTL_OP_DIOCGMEDIASIZE;
- sysio()->ioctl_in.argp = 0;
-
- break;
- }
-
- case TIOCSETA:
- {
- /* not implemented but used by e.g. vim */
- break;
- }
-
-
- default:
-
- warning("unsupported ioctl (request=", Hex(request), ")");
- break;
- }
-
- if (sysio()->ioctl_in.request == Vfs::File_io_service::IOCTL_OP_UNDEFINED) {
- errno = ENOTTY;
- return -1;
- }
-
- /* perform syscall */
- if (!noux_syscall(Noux::Session::SYSCALL_IOCTL)) {
- switch (sysio()->error.ioctl) {
- case Vfs::File_io_service::IOCTL_ERR_INVALID: errno = EINVAL; break;
- case Vfs::File_io_service::IOCTL_ERR_NOTTY: errno = ENOTTY; break;
- default: errno = 0; break;
- }
-
- return -1;
- }
-
- /*
- * Unmarshal ioctl results
- */
- switch (request) {
-
- case TIOCGWINSZ:
- {
- ::winsize *winsize = (::winsize *)argp;
- winsize->ws_row = sysio()->ioctl_out.tiocgwinsz.rows;
- winsize->ws_col = sysio()->ioctl_out.tiocgwinsz.columns;
- return 0;
- }
- case TIOCSETAF:
- case TIOCSETAW:
- return 0;
-
- case FIONBIO:
- return 0;
- case DIOCGMEDIASIZE:
- {
- int64_t *disk_size = (int64_t*)argp;
- *disk_size = sysio()->ioctl_out.diocgmediasize.size;
- return 0;
- }
-
- default:
- return -1;
- }
- }
-
-
- int Plugin::pipe(Libc::File_descriptor *pipefd[2])
- {
- /* perform syscall */
- if (!noux_syscall(Noux::Session::SYSCALL_PIPE)) {
- error("pipe error");
- /* XXX set errno */
- return -1;
- }
-
- for (int i = 0; i < 2; i++) {
- Libc::Plugin_context *context = noux_context(sysio()->pipe_out.fd[i]);
- pipefd[i] = Libc::file_descriptor_allocator()->alloc(this, context, sysio()->pipe_out.fd[i]);
- }
- return 0;
- }
-
-
- Libc::File_descriptor *Plugin::dup(Libc::File_descriptor* fd)
- {
- sysio()->dup2_in.fd = noux_fd(fd->context);
- sysio()->dup2_in.to_fd = -1;
-
- if (!noux_syscall(Noux::Session::SYSCALL_DUP2)) {
- error("dup error");
- /* XXX set errno */
- return 0;
- }
-
- Libc::Plugin_context *context = noux_context(sysio()->dup2_out.fd);
- return Libc::file_descriptor_allocator()->alloc(this, context,
- sysio()->dup2_out.fd);
- }
-
-
- int Plugin::dup2(Libc::File_descriptor *fd, Libc::File_descriptor *new_fd)
- {
- /*
- * We use a one-to-one mapping of libc fds and Noux fds.
- */
- new_fd->context = noux_context(new_fd->libc_fd);
-
- sysio()->dup2_in.fd = noux_fd(fd->context);
- sysio()->dup2_in.to_fd = noux_fd(new_fd->context);
-
- /* perform syscall */
- if (!noux_syscall(Noux::Session::SYSCALL_DUP2)) {
- error("dup2 error");
- /* XXX set errno */
- return -1;
- }
-
- return noux_fd(new_fd->context);
- }
-
-
- int Plugin::fstat(Libc::File_descriptor *fd, struct stat *buf)
- {
- sysio()->fstat_in.fd = noux_fd(fd->context);
- if (!noux_syscall(Noux::Session::SYSCALL_FSTAT)) {
- error("fstat error");
- /* XXX set errno */
- return -1;
- }
-
- _sysio_to_stat_struct(sysio(), buf);
- return 0;
- }
-
-
- int Plugin::fsync(Libc::File_descriptor *fd)
- {
- if (verbose)
- warning(__func__, ": not implemented");
- return 0;
- }
-
-
- int Plugin::ftruncate(Libc::File_descriptor *fd, ::off_t length)
- {
- sysio()->ftruncate_in.fd = noux_fd(fd->context);
- sysio()->ftruncate_in.length = length;
- if (!noux_syscall(Noux::Session::SYSCALL_FTRUNCATE)) {
- switch (sysio()->error.ftruncate) {
- case Vfs::File_io_service::FTRUNCATE_OK: /* never reached */
- case Vfs::File_io_service::FTRUNCATE_ERR_NO_PERM: errno = EPERM; break;
- case Vfs::File_io_service::FTRUNCATE_ERR_INTERRUPT: errno = EINTR; break;
- case Vfs::File_io_service::FTRUNCATE_ERR_NO_SPACE: errno = ENOSPC; break;
- }
- return -1;
- }
-
- return 0;
- }
-
-
- int Plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
- {
- /* copy arguments to sysio */
- sysio()->fcntl_in.fd = noux_fd(fd->context);
- switch (cmd) {
-
- case F_DUPFD_CLOEXEC:
- case F_DUPFD:
- {
- /*
- * Allocate free file descriptor locally. Noux FDs are expected
- * to correspond one-to-one to libc FDs.
- */
- Libc::File_descriptor *new_fd =
- Libc::file_descriptor_allocator()->alloc(this, 0);
- new_fd->path(fd->fd_path);
-
- /*
- * Use new allocated number as name of file descriptor
- * duplicate.
- */
- if (dup2(fd, new_fd) == -1) {
- error("Plugin::fcntl: dup2 unexpectedly failed");
- errno = EINVAL;
- return -1;
- }
-
- return new_fd->libc_fd;
- }
-
- case F_GETFD:
- sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_GET_FD_FLAGS;
- break;
-
- case F_SETFD:
- sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_SET_FD_FLAGS;
- sysio()->fcntl_in.long_arg = arg;
- break;
-
- case F_GETFL:
- if (verbose)
- log("fcntl: F_GETFL for libc_fd=", fd->libc_fd);
- sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_GET_FILE_STATUS_FLAGS;
- break;
-
- case F_SETFL:
- if (verbose)
- log("fcntl: F_SETFL for libc_fd=", fd->libc_fd);
- sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_SET_FILE_STATUS_FLAGS;
- sysio()->fcntl_in.long_arg = arg;
- break;
-
- default:
- error("fcntl: unsupported command ", cmd);
- errno = EINVAL;
- return -1;
- };
-
- /* invoke system call */
- if (!noux_syscall(Noux::Session::SYSCALL_FCNTL)) {
- warning("fcntl failed (libc_fd=", fd->libc_fd, ", cmd=", Hex(cmd), ")");
- switch (sysio()->error.fcntl) {
- case Noux::Sysio::FCNTL_ERR_CMD_INVALID: errno = EINVAL; break;
- default:
- switch (sysio()->error.general) {
- case Vfs::Directory_service::ERR_FD_INVALID: errno = EINVAL; break;
- case Vfs::Directory_service::NUM_GENERAL_ERRORS: break;
- }
- }
- return -1;
- }
-
- /* read result from sysio */
- return sysio()->fcntl_out.result;
- }
-
-
- ssize_t Plugin::getdirentries(Libc::File_descriptor *fd, char *buf,
- ::size_t nbytes, ::off_t *basep)
- {
- if (nbytes < sizeof(struct dirent)) {
- error("buf too small");
- return -1;
- }
-
- sysio()->dirent_in.fd = noux_fd(fd->context);
-
- if (!noux_syscall(Noux::Session::SYSCALL_DIRENT)) {
- switch (sysio()->error.general) {
-
- case Vfs::Directory_service::ERR_FD_INVALID:
- errno = EBADF;
- error("dirent: ERR_FD_INVALID");
- return -1;
-
- case Vfs::Directory_service::NUM_GENERAL_ERRORS: return -1;
- }
- }
-
- using Dirent_type = Vfs::Directory_service::Dirent_type;
-
- if (sysio()->dirent_out.entry.type == Dirent_type::END)
- return 0;
-
- auto d_type = [] (Dirent_type const &type)
- {
- switch (sysio()->dirent_out.entry.type) {
- case Dirent_type::DIRECTORY: return DT_DIR;
- case Dirent_type::CONTINUOUS_FILE: return DT_REG;
- case Dirent_type::TRANSACTIONAL_FILE: return DT_REG;
- case Dirent_type::SYMLINK: return DT_LNK;
- case Dirent_type::END: return 0;
- }
- return 0;
- };
-
- struct dirent &dirent = *(struct dirent *)buf;
-
- dirent = { };
-
- dirent.d_type = d_type(sysio()->dirent_out.entry.type);
- dirent.d_fileno = sysio()->dirent_out.entry.fileno;
- dirent.d_reclen = sizeof(struct dirent);
-
- Genode::strncpy(dirent.d_name, sysio()->dirent_out.entry.name,
- sizeof(dirent.d_name));
-
- dirent.d_namlen = Genode::strlen(dirent.d_name);
-
- *basep += sizeof(struct dirent);
- return sizeof(struct dirent);
- }
-
-
- ::off_t Plugin::lseek(Libc::File_descriptor *fd,
- ::off_t offset, int whence)
- {
- sysio()->lseek_in.fd = noux_fd(fd->context);
- sysio()->lseek_in.offset = offset;
-
- switch (whence) {
- default:
- case SEEK_SET: sysio()->lseek_in.whence = Noux::Sysio::LSEEK_SET; break;
- case SEEK_CUR: sysio()->lseek_in.whence = Noux::Sysio::LSEEK_CUR; break;
- case SEEK_END: sysio()->lseek_in.whence = Noux::Sysio::LSEEK_END; break;
- }
-
- if (!noux_syscall(Noux::Session::SYSCALL_LSEEK)) {
- switch (sysio()->error.general) {
-
- case Vfs::Directory_service::ERR_FD_INVALID:
- errno = EBADF;
- error("lseek: ERR_FD_INVALID");
- return -1;
-
- case Vfs::Directory_service::NUM_GENERAL_ERRORS: return -1;
- }
- }
-
- return sysio()->lseek_out.offset;
- }
-
-
- int Plugin::unlink(char const *path)
- {
- Genode::strncpy(sysio()->unlink_in.path, path, sizeof(sysio()->unlink_in.path));
-
- if (!noux_syscall(Noux::Session::SYSCALL_UNLINK)) {
- warning("unlink syscall failed for path \"", path, "\"");
- typedef Vfs::Directory_service::Unlink_result Result;
- switch (sysio()->error.unlink) {
- case Result::UNLINK_ERR_NO_ENTRY: errno = ENOENT; break;
- case Result::UNLINK_ERR_NOT_EMPTY: errno = ENOTEMPTY; break;
- case Result::UNLINK_ERR_NO_PERM: errno = EPERM; break;
- case Result::UNLINK_OK: break; /* only here to complete the enumeration */
- }
- return -1;
- }
-
- return 0;
- }
-
-
- int Plugin::rmdir(char const *path)
- {
- return Plugin::unlink(path);
- }
-
-
- ssize_t Plugin::readlink(const char *path, char *buf, ::size_t bufsiz)
- {
- if (verbose)
- log(__func__, ": path=", path, ", bufsiz=", bufsiz);
-
- Genode::strncpy(sysio()->readlink_in.path, path, sizeof(sysio()->readlink_in.path));
- sysio()->readlink_in.bufsiz = bufsiz;
-
- if (!noux_syscall(Noux::Session::SYSCALL_READLINK)) {
- warning("readlink syscall failed for path \"", path, "\"");
- switch (sysio()->error.readlink) {
- case Noux::Sysio::READLINK_ERR_NO_ENTRY: errno = ENOENT; return -1;
- case Noux::Sysio::READLINK_ERR_NO_PERM: errno = EPERM; return -1;
- }
- }
-
- ssize_t size = Genode::min((size_t)sysio()->readlink_out.count, bufsiz);
-
- Genode::memcpy(buf, sysio()->readlink_out.chunk, size);
-
- if (verbose)
- log(__func__, ": result=", Genode::Cstring(buf));
-
- return size;
- }
-
-
- int Plugin::rename(char const *from_path, char const *to_path)
- {
- Genode::strncpy(sysio()->rename_in.from_path, from_path, sizeof(sysio()->rename_in.from_path));
- Genode::strncpy(sysio()->rename_in.to_path, to_path, sizeof(sysio()->rename_in.to_path));
-
- if (!noux_syscall(Noux::Session::SYSCALL_RENAME)) {
- warning("rename syscall failed for \"", from_path, "\" -> \"", to_path, "\"");
- switch (sysio()->error.rename) {
- case Vfs::Directory_service::RENAME_ERR_NO_ENTRY: errno = ENOENT; break;
- case Vfs::Directory_service::RENAME_ERR_CROSS_FS: errno = EXDEV; break;
- case Vfs::Directory_service::RENAME_ERR_NO_PERM: errno = EPERM; break;
- default: errno = EPERM; break;
- }
- return -1;
- }
-
- return 0;
- }
-
-
- int Plugin::mkdir(const char *path, mode_t mode)
- {
- Genode::strncpy(sysio()->mkdir_in.path, path, sizeof(sysio()->mkdir_in.path));
-
- if (!noux_syscall(Noux::Session::SYSCALL_MKDIR)) {
- warning("mkdir syscall failed for \"", path, "\" mode=", Hex(mode));
- switch (sysio()->error.mkdir) {
- case Noux::Sysio::MKDIR_ERR_EXISTS: errno = EEXIST; break;
- case Noux::Sysio::MKDIR_ERR_NO_ENTRY: errno = ENOENT; break;
- case Noux::Sysio::MKDIR_ERR_NO_SPACE: errno = ENOSPC; break;
- case Noux::Sysio::MKDIR_ERR_NAME_TOO_LONG: errno = ENAMETOOLONG; break;
- case Noux::Sysio::MKDIR_ERR_NO_PERM: errno = EPERM; break;
- default: errno = EPERM; break;
- }
- return -1;
- }
- return 0;
- }
-
-
- void *Plugin::mmap(void *addr_in, ::size_t length, int prot, int flags,
- Libc::File_descriptor *fd, ::off_t offset)
- {
- if (prot != PROT_READ) {
- error("mmap for prot=", Hex(prot), " not supported");
- errno = EACCES;
- return (void *)-1;
- }
-
- if (addr_in != 0) {
- error("mmap for predefined address not supported");
- errno = EINVAL;
- return (void *)-1;
- }
-
- void *addr = Libc::mem_alloc()->alloc(length, PAGE_SHIFT);
- if (addr == (void *)-1) {
- errno = ENOMEM;
- return (void *)-1;
- }
-
- if (::pread(fd->libc_fd, addr, length, offset) < 0) {
- error("mmap could not obtain file content");
- ::munmap(addr, length);
- errno = EACCES;
- return (void *)-1;
- }
-
- return addr;
- }
-
-
- int Plugin::munmap(void *addr, ::size_t)
- {
- Libc::mem_alloc()->free(addr);
- return 0;
- }
-
-
- Libc::File_descriptor *Plugin::socket(int domain, int type, int protocol)
- {
- sysio()->socket_in.domain = domain;
- sysio()->socket_in.type = type;
- sysio()->socket_in.protocol = protocol;
-
- if (!noux_syscall(Noux::Session::SYSCALL_SOCKET))
- return 0;
-
- Libc::Plugin_context *context = noux_context(sysio()->socket_out.fd);
- return Libc::file_descriptor_allocator()->alloc(this, context,
- sysio()->socket_out.fd);
- }
-
-
- int Plugin::getsockopt(Libc::File_descriptor *fd, int level, int optname,
- void *optval, socklen_t *optlen)
- {
- sysio()->getsockopt_in.fd = noux_fd(fd->context);
- sysio()->getsockopt_in.level = level;
- sysio()->getsockopt_in.optname = optname;
-
- /* wipe-old state */
- sysio()->getsockopt_in.optlen = *optlen;
- Genode::memset(sysio()->getsockopt_in.optval, 0,
- sizeof (sysio()->getsockopt_in.optval));
-
- if (!noux_syscall(Noux::Session::SYSCALL_GETSOCKOPT))
- return -1;
-
- Genode::memcpy(optval, sysio()->setsockopt_in.optval,
- sysio()->getsockopt_in.optlen);
-
- return 0;
- }
-
-
- int Plugin::setsockopt(Libc::File_descriptor *fd, int level, int optname,
- const void *optval, socklen_t optlen)
- {
- if (optlen > sizeof(sysio()->setsockopt_in.optval)) {
- /* XXX */
- return -1;
- }
-
- sysio()->setsockopt_in.fd = noux_fd(fd->context);
- sysio()->setsockopt_in.level = level;
- sysio()->setsockopt_in.optname = optname;
- sysio()->setsockopt_in.optlen = optlen;
-
- Genode::memcpy(sysio()->setsockopt_in.optval, optval, optlen);
-
- if (!noux_syscall(Noux::Session::SYSCALL_SETSOCKOPT)) {
- /* XXX */
- return -1;
- }
-
- return 0;
- }
-
-
- Libc::File_descriptor *Plugin::accept(Libc::File_descriptor *fd, struct sockaddr *addr,
- socklen_t *addrlen)
- {
- sysio()->accept_in.fd = noux_fd(fd->context);
-
- if (addr != NULL) {
- Genode::memcpy(&sysio()->accept_in.addr, addr, sizeof (struct sockaddr));
- sysio()->accept_in.addrlen = *addrlen;
- }
- else {
- Genode::memset(&sysio()->accept_in.addr, 0, sizeof (struct sockaddr));
- sysio()->accept_in.addrlen = 0;
- }
-
- if (!noux_syscall(Noux::Session::SYSCALL_ACCEPT)) {
- switch (sysio()->error.accept) {
- case Noux::Sysio::ACCEPT_ERR_AGAIN: errno = EAGAIN; break;
- case Noux::Sysio::ACCEPT_ERR_NO_MEMORY: errno = ENOMEM; break;
- case Noux::Sysio::ACCEPT_ERR_INVALID: errno = EINVAL; break;
- case Noux::Sysio::ACCEPT_ERR_NOT_SUPPORTED: errno = EOPNOTSUPP; break;
- case Noux::Sysio::ACCEPT_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
- default: errno = 0; break;
- }
-
- return 0;
- }
-
- if (addr != NULL)
- *addrlen = sysio()->accept_in.addrlen;
-
- Libc::Plugin_context *context = noux_context(sysio()->accept_out.fd);
- return Libc::file_descriptor_allocator()->alloc(this, context,
- sysio()->accept_out.fd);
- }
-
-
- int Plugin::bind(Libc::File_descriptor *fd, const struct sockaddr *addr,
- socklen_t addrlen)
- {
- sysio()->bind_in.fd = noux_fd(fd->context);
-
- Genode::memcpy(&sysio()->bind_in.addr, addr, sizeof (struct sockaddr));
- sysio()->bind_in.addrlen = addrlen;
-
- if (!noux_syscall(Noux::Session::SYSCALL_BIND)) {
- switch (sysio()->error.bind) {
- case Noux::Sysio::BIND_ERR_ACCESS: errno = EACCES; break;
- case Noux::Sysio::BIND_ERR_ADDR_IN_USE: errno = EADDRINUSE; break;
- case Noux::Sysio::BIND_ERR_INVALID: errno = EINVAL; break;
- case Noux::Sysio::BIND_ERR_NO_MEMORY: errno = ENOMEM; break;
- default: errno = 0; break;
- }
- return -1;
- }
-
- return 0;
- }
-
-
- int Plugin::connect(Libc::File_descriptor *fd, const struct sockaddr *addr,
- socklen_t addrlen)
- {
- sysio()->connect_in.fd = noux_fd(fd->context);
-
- Genode::memcpy(&sysio()->connect_in.addr, addr, sizeof (struct sockaddr));
- sysio()->connect_in.addrlen = addrlen;
-
- if (!noux_syscall(Noux::Session::SYSCALL_CONNECT)) {
- switch (sysio()->error.connect) {
- case Noux::Sysio::CONNECT_ERR_AGAIN: errno = EAGAIN; break;
- case Noux::Sysio::CONNECT_ERR_ALREADY: errno = EALREADY; break;
- case Noux::Sysio::CONNECT_ERR_ADDR_IN_USE: errno = EADDRINUSE; break;
- case Noux::Sysio::CONNECT_ERR_IN_PROGRESS: errno = EINPROGRESS; break;
- case Noux::Sysio::CONNECT_ERR_IS_CONNECTED: errno = EISCONN; break;
- case Noux::Sysio::CONNECT_ERR_RESET: errno = ECONNRESET; break;
- case Noux::Sysio::CONNECT_ERR_ABORTED: errno = ECONNABORTED; break;
- case Noux::Sysio::CONNECT_ERR_NO_ROUTE: errno = EHOSTUNREACH; break;
- default: errno = 0; break;
- }
- return -1;
- }
-
- return 0;
- }
-
-
- int Plugin::getpeername(Libc::File_descriptor *fd, struct sockaddr *addr,
- socklen_t *addrlen)
- {
- sysio()->getpeername_in.fd = noux_fd(fd->context);
- sysio()->getpeername_in.addrlen = *addrlen;
-
- if (!noux_syscall(Noux::Session::SYSCALL_GETPEERNAME)) {
- /* errno */
- return -1;
- }
-
- Genode::memcpy(addr, &sysio()->getpeername_in.addr,
- sizeof (struct sockaddr));
- *addrlen = sysio()->getpeername_in.addrlen;
-
- return 0;
- }
-
-
- int Plugin::listen(Libc::File_descriptor *fd, int backlog)
- {
- sysio()->listen_in.fd = noux_fd(fd->context);
- sysio()->listen_in.backlog = backlog;
-
- if (!noux_syscall(Noux::Session::SYSCALL_LISTEN)) {
- switch (sysio()->error.listen) {
- case Noux::Sysio::LISTEN_ERR_ADDR_IN_USE: errno = EADDRINUSE; break;
- case Noux::Sysio::LISTEN_ERR_NOT_SUPPORTED: errno = EOPNOTSUPP; break;
- default: errno = 0; break;
- }
- return -1;
- }
-
- return 0;
- }
-
-
- ssize_t Plugin::recv(Libc::File_descriptor *fd, void *buf, ::size_t len, int flags)
- {
- if (!buf) { errno = EFAULT; return -1; }
-
- Genode::size_t sum_recv_count = 0;
-
- while (len > 0) {
- Genode::size_t curr_len =
- Genode::min(len, sizeof(sysio()->recv_in.buf));
-
- sysio()->recv_in.fd = noux_fd(fd->context);
- sysio()->recv_in.len = curr_len;
-
- if (!noux_syscall(Noux::Session::SYSCALL_RECV)) {
- switch (sysio()->error.recv) {
- case Noux::Sysio::RECV_ERR_AGAIN: errno = EAGAIN; break;
- case Noux::Sysio::RECV_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
- case Noux::Sysio::RECV_ERR_INVALID: errno = EINVAL; break;
- case Noux::Sysio::RECV_ERR_NOT_CONNECTED: errno = ENOTCONN; break;
- default: errno = 0; break;
- }
- return -1;
- }
-
- Genode::memcpy((char *)buf + sum_recv_count,
- sysio()->recv_in.buf, sysio()->recv_out.len);
-
- sum_recv_count += sysio()->recv_out.len;
-
- if (sysio()->recv_out.len < curr_len)
- break;
-
- if (sysio()->recv_out.len <= len)
- len -= sysio()->recv_out.len;
- else
- break;
- }
-
- return sum_recv_count;
- }
-
-
- ssize_t Plugin::recvfrom(Libc::File_descriptor *fd, void *buf, ::size_t len, int flags,
- struct sockaddr *src_addr, socklen_t *addrlen)
- {
- if (!buf) { errno = EFAULT; return -1; }
-
- Genode::size_t sum_recvfrom_count = 0;
-
- while (len > 0) {
- Genode::size_t curr_len = Genode::min(len, sizeof(sysio()->recvfrom_in.buf));
-
- sysio()->recv_in.fd = noux_fd(fd->context);
- sysio()->recv_in.len = curr_len;
-
- if (addrlen == NULL)
- sysio()->recvfrom_in.addrlen = 0;
- else
- sysio()->recvfrom_in.addrlen = *addrlen;
-
- if (!noux_syscall(Noux::Session::SYSCALL_RECVFROM)) {
- switch (sysio()->error.recv) {
- case Noux::Sysio::RECV_ERR_AGAIN: errno = EAGAIN; break;
- case Noux::Sysio::RECV_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
- case Noux::Sysio::RECV_ERR_INVALID: errno = EINVAL; break;
- case Noux::Sysio::RECV_ERR_NOT_CONNECTED: errno = ENOTCONN; break;
- default: errno = 0; break;
- }
- return -1;
- }
-
- if (src_addr != NULL && addrlen != NULL)
- Genode::memcpy(src_addr, &sysio()->recvfrom_in.src_addr,
- sysio()->recvfrom_in.addrlen);
-
-
- Genode::memcpy((char *)buf + sum_recvfrom_count,
- sysio()->recvfrom_in.buf, sysio()->recvfrom_out.len);
-
- sum_recvfrom_count += sysio()->recvfrom_out.len;
-
- if (sysio()->recvfrom_out.len < curr_len)
- break;
-
- if (sysio()->recvfrom_out.len <= len)
- len -= sysio()->recvfrom_out.len;
- else
- break;
- }
-
- return sum_recvfrom_count;
- }
-
-
- ssize_t Plugin::send(Libc::File_descriptor *fd, const void *buf, ::size_t len, int flags)
- {
- if (!buf) { errno = EFAULT; return -1; }
-
- /* remember original len for the return value */
- int const orig_count = len;
- char *src = (char *)buf;
-
- while (len > 0) {
-
- Genode::size_t curr_len = Genode::min(sizeof (sysio()->send_in.buf), len);
-
- sysio()->send_in.fd = noux_fd(fd->context);
- sysio()->send_in.len = curr_len;
- Genode::memcpy(sysio()->send_in.buf, src, curr_len);
-
- if (!noux_syscall(Noux::Session::SYSCALL_SEND)) {
- error("write error ", (int)sysio()->error.general);
- switch (sysio()->error.send) {
- case Noux::Sysio::SEND_ERR_AGAIN: errno = EAGAIN; break;
- case Noux::Sysio::SEND_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
- case Noux::Sysio::SEND_ERR_CONNECTION_RESET: errno = ECONNRESET; break;
- case Noux::Sysio::SEND_ERR_INVALID: errno = EINVAL; break;
- case Noux::Sysio::SEND_ERR_IS_CONNECTED: errno = EISCONN; break;
- case Noux::Sysio::SEND_ERR_NO_MEMORY: errno = ENOMEM; break;
- default: errno = 0; break;
- }
- /* return foo */
- }
-
- len -= curr_len;
- src += curr_len;
- }
- return orig_count;
- }
-
-
- ssize_t Plugin::sendto(Libc::File_descriptor *fd, const void *buf, size_t len, int flags,
- const struct sockaddr *dest_addr, socklen_t addrlen)
- {
- if (!buf) { errno = EFAULT; return -1; }
-
- int const orig_count = len;
-
- if (addrlen > sizeof (sysio()->sendto_in.dest_addr)) {
- errno = 0; /* XXX */
- return -1;
- }
-
- /* wipe-out sendto buffer */
- Genode::memset(sysio()->sendto_in.buf, 0, sizeof (sysio()->sendto_in.buf));
-
- char *src = (char *)buf;
- while (len > 0) {
- size_t curr_len = Genode::min(sizeof (sysio()->sendto_in.buf), len);
-
- sysio()->sendto_in.fd = noux_fd(fd->context);
- sysio()->sendto_in.len = curr_len;
- Genode::memcpy(sysio()->sendto_in.buf, src, curr_len);
-
- if (addrlen == 0) {
- sysio()->sendto_in.addrlen = 0;
- Genode::memset(&sysio()->sendto_in.dest_addr, 0, sizeof (struct sockaddr));
- }
- else {
- sysio()->sendto_in.addrlen = addrlen;
- Genode::memcpy(&sysio()->sendto_in.dest_addr, dest_addr, addrlen);
- }
-
- if (!noux_syscall(Noux::Session::SYSCALL_SENDTO)) {
- switch (sysio()->error.send) {
- case Noux::Sysio::SEND_ERR_AGAIN: errno = EAGAIN; break;
- case Noux::Sysio::SEND_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
- case Noux::Sysio::SEND_ERR_CONNECTION_RESET: errno = ECONNRESET; break;
- case Noux::Sysio::SEND_ERR_INVALID: errno = EINVAL; break;
- case Noux::Sysio::SEND_ERR_IS_CONNECTED: errno = EISCONN; break;
- case Noux::Sysio::SEND_ERR_NO_MEMORY: errno = ENOMEM; break;
- default: errno = 0; break;
- }
- return -1;
- }
-
- len -= curr_len;
- src += curr_len;
- }
-
- return orig_count;
- }
-
-
- int Plugin::shutdown(Libc::File_descriptor *fd, int how)
- {
- sysio()->shutdown_in.fd = noux_fd(fd->context);
- sysio()->shutdown_in.how = how;
-
- if (!noux_syscall(Noux::Session::SYSCALL_SHUTDOWN)) {
- switch (sysio()->error.shutdown) {
- case Noux::Sysio::SHUTDOWN_ERR_NOT_CONNECTED: errno = ENOTCONN; break;
- default: errno = 0; break;
- }
- return -1;
- }
-
- return 0;
- }
-
-} /* unnamed namespace */
-
-
-/**************************************
- ** Obtaining command-line arguments **
- **************************************/
-
-/* external symbols provided by Genode's startup code */
-extern char **genode_argv;
-extern int genode_argc;
-extern char **genode_envp;
-
-/* pointer to environment, provided by libc */
-extern char **environ;
-
-
-/* register noux libc plugin at libc */
-static Plugin noux_plugin;
-
-
-void Plugin::init(Genode::Env &env)
-{
- _env_ptr = &env;
- noux_connection();
-
- /* register inherited open file descriptors */
- int fd = 0;
- while ((fd = noux()->next_open_fd(fd)) != -1) {
- Libc::file_descriptor_allocator()->alloc(this, noux_context(fd), fd);
- fd++;
- }
-
- sigemptyset(&signal_mask);
-
- /* copy command-line arguments from 'args' ROM dataspace */
- enum { MAX_ARGS = 256, ARG_BUF_SIZE = sizeof(Noux::Sysio::Args) };
- static char *argv[MAX_ARGS];
- static char arg_buf[ARG_BUF_SIZE];
- {
- Genode::Attached_rom_dataspace ds(env, "args");
- Genode::memcpy(arg_buf, ds.local_addr(),
- Genode::min((size_t)ARG_BUF_SIZE, ds.size()));
- }
-
- int argc = 0;
- for (unsigned i = 0; arg_buf[i] && (i < ARG_BUF_SIZE - 2); ) {
-
- if (i >= ARG_BUF_SIZE - 2) {
- warning("command-line argument buffer exceeded");
- break;
- }
-
- if (argc >= MAX_ARGS - 1) {
- warning("number of command-line arguments exceeded");
- break;
- }
-
- argv[argc] = &arg_buf[i];
- i += Genode::strlen(&arg_buf[i]) + 1; /* skip null-termination */
- argc++;
- }
-
- /* register command-line arguments at Genode's startup code */
- genode_argv = argv;
- genode_argc = argc;
-
- /*
- * Make environment variables from 'env' ROM dataspace available to libc's
- * 'environ'.
- */
- enum { ENV_MAX_ENTRIES = 128, ENV_BUF_SIZE = 8*1024 };
- static char *env_array[ENV_MAX_ENTRIES];
- static char env_buf[ENV_BUF_SIZE];
- {
- Genode::Attached_rom_dataspace ds(env, "env");
- Genode::memcpy(env_buf, ds.local_addr(),
- Genode::min((size_t)ENV_BUF_SIZE, ds.size()));
- }
- char *env_string = &env_buf[0];
-
- unsigned num_entries = 0; /* index within 'env_array' */
-
- static Libc::Absolute_path noux_cwd("/");
-
- while (*env_string && (num_entries < ENV_MAX_ENTRIES - 1)) {
- if ((strlen(env_string) >= strlen("NOUX_CWD=")) &&
- (strncmp(env_string, "NOUX_CWD=", strlen("NOUX_CWD=")) == 0)) {
- noux_cwd.import(&env_string[strlen("NOUX_CWD=")]);
- } else {
- env_array[num_entries++] = env_string;
- }
- env_string += (strlen(env_string) + 1);
- }
- env_array[num_entries] = 0;
-
- /* register list of environment variables at libc 'environ' pointer */
- environ = env_array;
-
- /* define env pointer to be passed to main function (in '_main.cc') */
- genode_envp = environ;
-
- chdir(noux_cwd.base());
-}
-
-
diff --git a/repos/ports/src/lib/libc_noux/target.mk b/repos/ports/src/lib/libc_noux/target.mk
deleted file mode 100644
index 402046338f..0000000000
--- a/repos/ports/src/lib/libc_noux/target.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-TARGET = libc_noux
-LIBS = posix libc_noux
-
-CC_CXX_WARN_STRICT =
diff --git a/repos/ports/src/noux/args.h b/repos/ports/src/noux/args.h
deleted file mode 100644
index 3eb4209e13..0000000000
--- a/repos/ports/src/noux/args.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * \brief Handling command-line for Noux processes
- * \author Norman Feske
- * \date 2011-01-17
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__ARGS_H_
-#define _NOUX__ARGS_H_
-
-/* Genode includes */
-#include
-#include
-#include
-
-namespace Noux {
- class Args;
- class Args_dataspace;
-}
-
-
-class Noux::Args
-{
- protected:
-
- char * const _buf;
- size_t const _buf_size;
- size_t _len;
-
- size_t _free_size() const
- {
- /*
- * Keep space for two trailing zeros, indicating the end of the
- * stream of strings.
- */
- return _buf_size - _len - 2;
- }
-
- public:
-
- class Overrun { };
-
- /**
- * Constructor
- *
- * \param buf argument buffer
- * \param buf_size size of argument buffer in character,
- * must be at least 2
- */
- Args(char *buf, size_t buf_size)
- : _buf(buf), _buf_size(buf_size), _len(0)
- {
- if (buf_size <= 2)
- throw Overrun();
-
- /* search end of string stream (two subsequent zeros) */
- for (; (_buf[_len] || _buf[_len + 1]) && (_len < _buf_size - 2); _len++);
-
- /* ensure termination of argument buffer */
- _buf[_buf_size - 1] = 0;
- _buf[_buf_size - 2] = 0;
- }
-
- Args() : _buf(0), _buf_size(0), _len(0) { }
-
- bool valid() const { return _buf_size > 0; }
-
- size_t len() const { return _len; }
-
- char const *base() const { return _buf; }
-
- void append(char const *arg)
- {
- size_t const arg_len = strlen(arg);
-
- if (arg_len > _free_size())
- throw Overrun();
-
- strncpy(_buf + _len, arg, _buf_size - _len);
-
- _len += arg_len + 1; /* keep null termination between strings */
-
- /* mark end of stream of strings */
- _buf[_len] = 0;
- }
-
- void dump()
- {
- for (unsigned i = 0, j = 0; _buf[i] && (i < _buf_size - 2);
- i += strlen(&_buf[i]) + 1, j++)
- log("arg(", j, "): \"", Cstring(&_buf[i]), "\"");
- }
-};
-
-
-struct Noux::Args_dataspace : private Attached_ram_dataspace, Args
-{
- Args_dataspace(Ram_allocator &ram, Region_map &rm,
- size_t size, Args const &from = Args())
- :
- Attached_ram_dataspace(ram, rm, size),
- Args(local_addr(), size)
- {
- if (from.len() > size - 2)
- throw Overrun();
-
- memcpy(_buf, from.base(), from.len() + 1);
- }
-
- using Attached_ram_dataspace::cap;
-};
-
-#endif /* _NOUX__ARGS_H_ */
diff --git a/repos/ports/src/noux/armed_timeout.h b/repos/ports/src/noux/armed_timeout.h
deleted file mode 100644
index ad1e2d4bcd..0000000000
--- a/repos/ports/src/noux/armed_timeout.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * \brief Timeout mechanism for 'select'
- * \author Norman Feske
- * \date 2011-02-14
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__ARMED_TIMEOUT_H_
-#define _NOUX__ARMED_TIMEOUT_H_
-
-#include
-
-namespace Noux { class Armed_timeout; }
-
-
-class Noux::Armed_timeout : Noncopyable
-{
- public:
-
- struct State : Noncopyable
- {
- State() { }
- bool timed_out { };
- };
-
- private:
-
- State &_state;
- Lock &_blocker;
-
- Timer::One_shot_timeout _one_shot_timeout;
-
- void _handle_one_shot_timeout(Duration)
- {
- _state.timed_out = true;
- _blocker.unlock();
- }
-
- public:
-
- Armed_timeout(State &state, Lock &blocker,
- Timer::Connection &timer, Microseconds microseconds)
- :
- _state(state), _blocker(blocker),
- _one_shot_timeout(timer, *this, &Armed_timeout::_handle_one_shot_timeout)
- {
- _state.timed_out = false;
- _one_shot_timeout.schedule(microseconds);
- }
-
- void discard() { _one_shot_timeout.discard(); }
-};
-
-#endif /* _NOUX__ARMED_TIMEOUT_H_ */
diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h
deleted file mode 100644
index 06acf98b0a..0000000000
--- a/repos/ports/src/noux/child.h
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * \brief Noux child process
- * \author Norman Feske
- * \date 2011-02-17
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__CHILD_H_
-#define _NOUX__CHILD_H_
-
-/* Genode includes */
-#include
-#include
-#include
-
-/* Noux includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace Noux {
-
- class Pid_allocator;
-
- /**
- * Return singleton instance of Io_receptor_registry
- */
- Io_receptor_registry *io_receptor_registry();
-
- /*
- * Return lock for protecting the signal queue
- */
- Genode::Lock &signal_lock();
-
- class Child_config;
- class Child;
-
- /**
- * Return true is child is the init process
- */
- bool init_process(Child *child);
- void init_process_exited(int);
-}
-
-
-/**
- * Allocator for process IDs
- */
-class Noux::Pid_allocator
-{
- private:
-
- Lock _lock { };
- int _num_pids { 0 };
-
- public:
-
- int alloc()
- {
- Lock::Guard guard(_lock);
- return _num_pids++;
- }
-};
-
-
-struct Noux::Child_config : Attached_ram_dataspace
-{
- enum { CONFIG_DS_SIZE = 4096 };
-
- Child_config(Ram_allocator &ram, Region_map &local_rm, Verbose const &verbose)
- :
- Attached_ram_dataspace(ram, local_rm, CONFIG_DS_SIZE)
- {
- Xml_generator xml(local_addr(), CONFIG_DS_SIZE, "config", [&] ()
- {
- if (verbose.ld())
- xml.attribute("ld_verbose", "yes");
-
- xml.node("ld", [&] () {
- xml.node("library", [&] () {
- xml.attribute("rom", "libc_noux.lib.so"); }); });
- });
- }
-};
-
-
-class Noux::Child : public Rpc_object,
- public File_descriptor_registry,
- public Family_member,
- public Destruct_queue::Element,
- public Interrupt_handler
-{
- private:
-
- /*
- * Noncopyable
- */
- Child(Child const &);
- Child &operator = (Child const &);
-
- Child_policy::Name const _name;
-
- Verbose const &_verbose;
-
- User_info const &_user_info;
-
- Time_info const &_time_info;
-
- Parent_exit *_parent_exit;
- Kill_broadcaster &_kill_broadcaster;
- Timer::Connection &_timer_connection;
- Parent_execve &_parent_execve;
- Pid_allocator &_pid_allocator;
-
- Env &_env;
-
- Vfs::File_system &_root_dir;
-
- Vfs_io_waiter_registry &_vfs_io_waiter_registry;
- Vfs_handle_context _vfs_handle_context { };
-
- Destruct_queue &_destruct_queue;
-
- void _handle_destruct() { _destruct_queue.insert(this); }
-
- Signal_handler _destruct_handler {
- _env.ep(), *this, &Child::_handle_destruct };
-
- Allocator &_heap;
-
- /**
- * Entrypoint used to serve the RPC interfaces of the
- * locally-provided services
- */
- enum { STACK_SIZE = 64*1024 };
- Rpc_entrypoint _ep { &_env.pd(), STACK_SIZE, "noux_process", false };
-
- Pd_session &_ref_pd;
- Pd_session_capability const _ref_pd_cap;
-
- /**
- * Registry of dataspaces owned by the Noux process
- */
- Dataspace_registry _ds_registry { _heap };
-
- /**
- * Locally-provided PD service
- */
- typedef Local_service Pd_service;
- Pd_session_component _pd { _heap, _env, _ep, _name, _ds_registry };
- Pd_service::Single_session_factory _pd_factory { _pd };
- Pd_service _pd_service { _pd_factory };
-
- /**
- * Locally-provided CPU service
- */
- typedef Local_service Cpu_service;
- Cpu_session_component _cpu { _env, _ep, _name, false, _ds_registry };
- Cpu_service::Single_session_factory _cpu_factory { _cpu };
- Cpu_service _cpu_service { _cpu_factory };
-
- /*
- * Locally-provided Noux service
- */
- Capability_guard _cap_guard { _ep, *this };
-
- typedef Local_service > Noux_service;
- Noux_service::Single_session_factory _noux_factory { *this };
- Noux_service _noux_service { _noux_factory };
-
- /*
- * Locally-provided ROM service
- */
- Empty_rom_factory _empty_rom_factory { _heap, _ep };
- Empty_rom_service _empty_rom_service { _empty_rom_factory };
- Local_rom_factory _rom_factory { _heap, _env, _ep, _root_dir,
- _vfs_io_waiter_registry, _ds_registry };
- Local_rom_service _rom_service { _rom_factory };
-
- /**
- * Command line arguments
- */
- enum { ARGS_DS_SIZE = sizeof(Sysio::Args) };
-
- Args_dataspace _args;
-
- /**
- * Environment variables
- */
- Environment _sysio_env;
-
- /*
- * Child configuration
- */
- Child_config _config { _ref_pd, _env.rm(), _verbose };
-
- enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) };
- enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) };
-
- Attached_ram_dataspace _sysio_ds { _ref_pd, _env.rm(), SYSIO_DS_SIZE };
- Sysio &_sysio = *_sysio_ds.local_addr();
-
- typedef Ring_buffer
- Signal_queue;
- Signal_queue _pending_signals { };
-
- Parent_services &_parent_services;
-
- Static_dataspace_info _sysio_ds_info;
- Static_dataspace_info _args_ds_info;
- Static_dataspace_info _sysio_env_ds_info;
- Static_dataspace_info _config_ds_info;
-
- Child_policy _child_policy;
-
- Genode::Child _child;
-
- /**
- * Exception type for failed file-descriptor lookup
- */
- class Invalid_fd { };
-
- Shared_pointer _lookup_channel(int fd) const
- {
- Shared_pointer channel = io_channel_by_fd(fd);
-
- if (channel)
- return channel;
-
- throw Invalid_fd();
- }
-
- /**
- * Let specified child inherit our file descriptors
- */
- void _assign_io_channels_to(Child *child, bool skip_when_close_on_execve_set)
- {
- for (int fd = 0; fd < MAX_FILE_DESCRIPTORS; fd++)
- if (fd_in_use(fd)) {
- if (skip_when_close_on_execve_set && close_fd_on_execve(fd))
- continue;
- child->add_io_channel(io_channel_by_fd(fd), fd);
- child->close_fd_on_execve(fd, close_fd_on_execve(fd));
- }
- }
-
- /**
- * Block until the IO channel is ready for reading or writing or an
- * exception occured.
- *
- * \param io the IO channel
- * \param rd check for data available for reading
- * \param wr check for readiness for writing
- * \param ex check for exceptions
- */
- void _block_for_io_channel(Shared_pointer &io,
- bool rd, bool wr, bool ex)
- {
- /* reset the blocker lock to the 'locked' state */
- _blocker.unlock();
- _blocker.lock();
-
- Wake_up_notifier notifier(&_blocker);
- io->register_wake_up_notifier(¬ifier);
-
- for (;;) {
- if (io->check_unblock(rd, wr, ex) ||
- !_pending_signals.empty())
- break;
-
- /* block (unless the lock got unlocked in the meantime) */
- _blocker.lock();
- }
-
- io->unregister_wake_up_notifier(¬ifier);
- }
-
- void _destruct()
- {
- _ep.dissolve(this);
-
- if (init_process(this))
- init_process_exited(_child_policy.exit_value());
- }
-
- public:
-
- struct Insufficient_memory : Exception { };
-
- /**
- * Constructor
- *
- * \param forked false if the child is spawned directly from
- * an executable binary (i.e., the init process,
- * or children created via execve, or
- * true if the child is a fork from another child
- *
- * \throw Insufficent_memory if the child could not be started by
- * the parent
- */
- Child(Child_policy::Name const &name,
- Verbose const &verbose,
- User_info const &user_info,
- Time_info const &time_info,
- Parent_exit *parent_exit,
- Kill_broadcaster &kill_broadcaster,
- Timer::Connection &timer_connection,
- Parent_execve &parent_execve,
- Pid_allocator &pid_allocator,
- int pid,
- Env &env,
- Vfs::File_system &root_dir,
- Vfs_io_waiter_registry &vfs_io_waiter_registry,
- Args const &args,
- Sysio::Env const &sysio_env,
- Allocator &heap,
- Pd_session &ref_pd,
- Pd_session_capability ref_pd_cap,
- Parent_services &parent_services,
- bool forked,
- Destruct_queue &destruct_queue)
- :
- Family_member(pid),
- Destruct_queue::Element(heap),
- _name(name),
- _verbose(verbose),
- _user_info(user_info),
- _time_info(time_info),
- _parent_exit(parent_exit),
- _kill_broadcaster(kill_broadcaster),
- _timer_connection(timer_connection),
- _parent_execve(parent_execve),
- _pid_allocator(pid_allocator),
- _env(env),
- _root_dir(root_dir),
- _vfs_io_waiter_registry(vfs_io_waiter_registry),
- _destruct_queue(destruct_queue),
- _heap(heap),
- _ref_pd (ref_pd), _ref_pd_cap (ref_pd_cap),
- _args(ref_pd, _env.rm(), ARGS_DS_SIZE, args),
- _sysio_env(_ref_pd, _env.rm(), sysio_env),
- _parent_services(parent_services),
- _sysio_ds_info(_ds_registry, _sysio_ds.cap()),
- _args_ds_info(_ds_registry, _args.cap()),
- _sysio_env_ds_info(_ds_registry, _sysio_env.cap()),
- _config_ds_info(_ds_registry, _config.cap()),
- _child_policy(name, forked,
- _args.cap(), _sysio_env.cap(), _config.cap(),
- _ep, _pd_service, _cpu_service,
- _noux_service, _empty_rom_service,
- _rom_service, _parent_services,
- *this, parent_exit, *this, _destruct_handler,
- ref_pd, ref_pd_cap,
- _verbose.enabled()),
- _child(_env.rm(), _ep, _child_policy)
- {
- if (_verbose.enabled())
- _args.dump();
-
- if (!_child.main_thread_cap().valid()) {
- _destruct();
- throw Insufficient_memory();
- }
- }
-
- ~Child() { _destruct(); }
-
- void start() { _ep.activate(); }
-
- void start_forked_main_thread(addr_t ip, addr_t sp, addr_t parent_cap_addr)
- {
- /* poke parent_cap_addr into child's address space */
- Capability::Raw const raw = _child.parent_cap().raw();
-
- _pd.poke(_env.rm(), parent_cap_addr, (char *)&raw, sizeof(raw));
-
- /* start execution of new main thread at supplied trampoline */
- _cpu.start_main_thread(ip, sp);
- }
-
- void submit_exit_signal()
- {
- if (init_process(this)) {
- log("init process exited");
-
- /* trigger exit of main event loop */
- init_process_exited(_child_policy.exit_value());
- } else {
- Signal_transmitter(_destruct_handler).submit();
- }
- }
-
- Pd_session_component &pd() { return _pd; }
-
- Dataspace_registry &ds_registry() { return _ds_registry; }
-
-
- /****************************
- ** Noux session interface **
- ****************************/
-
- Dataspace_capability sysio_dataspace() override
- {
- return _sysio_ds.cap();
- }
-
- Capability lookup_region_map(addr_t const addr) override
- {
- return _pd.lookup_region_map(addr);
- }
-
- bool syscall(Syscall sc) override;
-
- int next_open_fd(int start_fd) override
- {
- if (start_fd >= 0)
- for (int fd = start_fd; fd < MAX_FILE_DESCRIPTORS; fd++)
- if (fd_in_use(fd))
- return fd;
- return -1;
- }
-
-
- /****************************************
- ** File_descriptor_registry overrides **
- ****************************************/
-
- /**
- * Find out if the IO channel associated with 'fd' has more file
- * descriptors associated with it
- */
- bool _is_the_only_fd_for_io_channel(int fd,
- Shared_pointer io_channel)
- {
- for (int f = 0; f < MAX_FILE_DESCRIPTORS; f++) {
- if ((f != fd) &&
- fd_in_use(f) &&
- (io_channel_by_fd(f) == io_channel))
- return false;
- }
-
- return true;
- }
-
- int add_io_channel(Shared_pointer io_channel, int fd = -1) override
- {
- fd = File_descriptor_registry::add_io_channel(io_channel, fd);
-
- /* Register the interrupt handler only once per IO channel */
- if (_is_the_only_fd_for_io_channel(fd, io_channel)) {
- Io_channel_listener *l = new (_heap) Io_channel_listener(this);
- io_channel->register_interrupt_handler(l);
- }
-
- return fd;
- }
-
- void remove_io_channel(int fd) override
- {
- Shared_pointer io_channel = _lookup_channel(fd);
-
- /*
- * Unregister the interrupt handler only if there are no other
- * file descriptors associated with the IO channel.
- */
- if (_is_the_only_fd_for_io_channel(fd, io_channel)) {
- Io_channel_listener *l = io_channel->lookup_io_channel_listener(this);
- io_channel->unregister_interrupt_handler(l);
- Genode::destroy(_heap, l);
- }
-
- File_descriptor_registry::remove_io_channel(fd);
- }
-
- void flush() override
- {
- for (int fd = 0; fd < MAX_FILE_DESCRIPTORS; fd++)
- try {
- remove_io_channel(fd);
- } catch (Invalid_fd) { }
- }
-
-
- /*****************************
- ** Family_member interface **
- *****************************/
-
- void submit_signal(Noux::Sysio::Signal sig) override
- {
- try {
- _pending_signals.add(sig);
- } catch (Signal_queue::Overflow) {
- error("signal queue is full - signal dropped");
- }
-
- _blocker.unlock();
- }
-
- Family_member *do_execve(const char *filename,
- Args const &args,
- Sysio::Env const &env) override
- {
- Lock::Guard signal_lock_guard(signal_lock());
-
- Child *child = new (_heap) Child(filename,
- _verbose,
- _user_info,
- _time_info,
- _parent_exit,
- _kill_broadcaster,
- _timer_connection,
- _parent_execve,
- _pid_allocator,
- pid(),
- _env,
- _root_dir,
- _vfs_io_waiter_registry,
- args,
- env,
- _heap,
- _ref_pd, _ref_pd_cap,
- _parent_services,
- false,
- _destruct_queue);
-
- _assign_io_channels_to(child, true);
-
- /* move the signal queue */
- while (!_pending_signals.empty())
- child->_pending_signals.add(_pending_signals.get());
-
- /*
- * Close all open files.
- *
- * This action is not part of the child destructor,
- * because in the case that a child exits itself,
- * it may need to close all files to unblock the
- * parent (which might be reading from a pipe) before
- * the parent can destroy the child object.
- */
- flush();
-
- /* signal main thread to remove ourself */
- Signal_transmitter(_destruct_handler).submit();
-
- /* start executing the new process */
- child->start();
-
- /* this child will be removed by the execve_finalization_dispatcher */
-
- return child;
- }
-
-
- /*********************************
- ** Interrupt_handler interface **
- *********************************/
-
- void handle_interrupt(Sysio::Signal signal) override
- {
- submit_signal(signal);
- }
-};
-
-#endif /* _NOUX__CHILD_H_ */
diff --git a/repos/ports/src/noux/child_env.h b/repos/ports/src/noux/child_env.h
deleted file mode 100644
index fc44663fe6..0000000000
--- a/repos/ports/src/noux/child_env.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * \brief Noux child environment
- * \author Christian Prochaska
- * \author Norman Feske
- * \date 2012-07-19
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__CHILD_ENV_H_
-#define _NOUX__CHILD_ENV_H_
-
-/* Genode includes */
-#include
-
-/* Noux includes */
-#include
-#include
-
-namespace Noux {
- template class Child_env;
- using namespace Genode;
-}
-
-
-/**
- * \param ARGS_SIZE size of the argument buffer given
- * to the constructor
- */
-template
-class Noux::Child_env
-{
- private:
-
- static unsigned constexpr MAX_LEN_INTERPRETER_LINE = 128;
-
- char const *_binary_name { nullptr };
- char _args[ARGS_SIZE + MAX_LEN_INTERPRETER_LINE];
- Sysio::Env _env;
-
- void _process_env(Sysio::Env env)
- {
- memcpy(_env, env, sizeof(Sysio::Env));
- }
-
- /**
- * Verify that the file exists and return its size
- */
- Vfs::file_size _file_size(Vfs::File_system &root_dir,
- char const *binary_name)
- {
- Vfs::Directory_service::Stat stat_out;
- Vfs::Directory_service::Stat_result stat_result;
-
- stat_result = root_dir.stat(binary_name, stat_out);
-
- switch (stat_result) {
- case Vfs::Directory_service::STAT_OK:
- break;
- case Vfs::Directory_service::STAT_ERR_NO_ENTRY:
- throw Binary_does_not_exist();
- case Vfs::Directory_service::STAT_ERR_NO_PERM:
- throw Binary_is_not_accessible();
- }
-
- return stat_out.size;
- }
-
- /**
- * Verify that the file is a valid ELF executable
- */
- void _verify_elf(char const *file)
- {
- if ((file[0] != 0x7f) ||
- (file[1] != 'E') ||
- (file[2] != 'L') ||
- (file[3] != 'F'))
- throw Binary_is_not_executable();
- }
-
- /**
- * Handle the case that the given binary needs an interpreter
- */
- void _process_binary_name_and_args(char const *binary_name,
- char const *args,
- Vfs::File_system &root_dir,
- Vfs_io_waiter_registry &vfs_io_waiter_registry,
- Ram_allocator &ram,
- Region_map &rm,
- Allocator &alloc)
- {
- Vfs::file_size binary_size = _file_size(root_dir, binary_name);
-
- if (binary_size == 0)
- throw Binary_is_not_executable();
-
- /*
- * We may have to check the dataspace twice because the binary
- * could be a script that uses an interpreter which might not
- * exist.
- */
- Reconstructible binary_ds {
- root_dir, vfs_io_waiter_registry,
- binary_name, ram, rm, alloc
- };
-
- if (!binary_ds->ds.valid())
- throw Binary_is_not_executable();
-
- Reconstructible attached_binary_ds(rm, binary_ds->ds);
-
- char const *binary_addr = attached_binary_ds->local_addr();
-
- /* look for '#!' */
- if ((binary_addr[0] != '#') || (binary_addr[1] != '!')) {
- _binary_name = binary_name;
- Genode::memcpy(_args, args, ARGS_SIZE);
- _verify_elf(binary_addr);
- return;
- }
-
- /* find end of line */
- Range_checked_index
- eol(2, min(binary_size, MAX_LEN_INTERPRETER_LINE));
-
- try {
- while (binary_addr[eol] != '\n') eol++;
- } catch (Index_out_of_range) { }
-
- /* skip leading spaces */
- Range_checked_index
- interpreter_line_cursor(2, eol);
-
- try {
- while (binary_addr[interpreter_line_cursor] == ' ')
- interpreter_line_cursor++;
- } catch (Index_out_of_range) { }
-
- /* no interpreter name found */
- if (interpreter_line_cursor == eol)
- throw Binary_does_not_exist();
-
- int interpreter_name_start = interpreter_line_cursor;
-
- /* find end of interpreter name */
- try {
- while (binary_addr[interpreter_line_cursor] != ' ')
- interpreter_line_cursor++;
- } catch (Index_out_of_range) { }
-
- size_t interpreter_name_len =
- interpreter_line_cursor - interpreter_name_start;
-
- /* copy interpreter name into argument buffer */
- unsigned int args_buf_cursor = 0;
- Genode::strncpy(&_args[args_buf_cursor],
- &binary_addr[interpreter_name_start],
- interpreter_name_len + 1);
- _binary_name = &_args[args_buf_cursor];
- args_buf_cursor += interpreter_name_len + 1;
-
- /* skip more spaces */
- try {
- while (binary_addr[interpreter_line_cursor] == ' ')
- interpreter_line_cursor++;
- } catch (Index_out_of_range) { }
-
- /* append interpreter arguments to argument buffer */
- size_t interpreter_args_len = eol - interpreter_line_cursor;
- if (interpreter_args_len > 0) {
- Genode::strncpy(&_args[args_buf_cursor],
- &binary_addr[interpreter_line_cursor],
- interpreter_args_len + 1);
- args_buf_cursor += interpreter_args_len + 1;
- }
-
- /* append script arguments to argument buffer */
- Genode::memcpy(&_args[args_buf_cursor],
- args, ARGS_SIZE);
-
- /* check if interpreter exists and is executable */
-
- binary_size = _file_size(root_dir, _binary_name);
-
- if (binary_size == 0)
- throw Binary_is_not_executable();
-
- binary_ds.construct(root_dir, vfs_io_waiter_registry,
- _binary_name, ram,
- rm, alloc);
-
- if (!binary_ds->ds.valid())
- throw Binary_is_not_executable();
-
- attached_binary_ds.construct(rm, binary_ds->ds);
-
- _verify_elf(attached_binary_ds->local_addr());
- }
-
- public:
-
- struct Binary_does_not_exist : Exception { };
- struct Binary_is_not_accessible : Exception { };
- struct Binary_is_not_executable : Exception { };
-
- Child_env(char const *binary_name,
- char const *args, Sysio::Env env,
- Vfs::File_system &root_dir,
- Vfs_io_waiter_registry &vfs_io_waiter_registry,
- Ram_allocator &ram,
- Region_map &rm,
- Allocator &alloc)
- {
- _process_env(env);
- _process_binary_name_and_args(binary_name, args, root_dir,
- vfs_io_waiter_registry,
- ram, rm, alloc);
- }
-
- char const *binary_name() const { return _binary_name; }
-
- Args args() { return Args(_args, sizeof(_args)); }
-
- Sysio::Env const &env() const { return _env; }
-};
-
-#endif /* _NOUX__CHILD_ENV_H_ */
diff --git a/repos/ports/src/noux/child_policy.h b/repos/ports/src/noux/child_policy.h
deleted file mode 100644
index 82dde83562..0000000000
--- a/repos/ports/src/noux/child_policy.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * \brief Noux child policy
- * \author Norman Feske
- * \date 2012-02-25
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__CHILD_POLICY_H_
-#define _NOUX__CHILD_POLICY_H_
-
-/* Genode includes */
-#include
-
-/* Noux includes */
-#include
-#include
-#include
-#include
-#include
-
-namespace Noux {
-
- typedef Registered Parent_service;
- typedef Registry Parent_services;
-
- typedef Local_service Pd_service;
- typedef Local_service Cpu_service;
- typedef Local_service > Noux_service;
-
- class Child_policy;
-}
-
-
-class Noux::Child_policy : public Genode::Child_policy
-{
- private:
-
- /**
- * Noncopyable
- */
- Child_policy(Child_policy const &);
- Child_policy &operator = (Child_policy const &);
-
- Name const _name;
- bool _forked;
- Init::Child_policy_provide_rom_file _args_policy;
- Init::Child_policy_provide_rom_file _env_policy;
- Init::Child_policy_provide_rom_file _config_policy;
- Pd_service &_pd_service;
- Cpu_service &_cpu_service;
- Noux_service &_noux_service;
- Empty_rom_service &_empty_rom_service;
- Local_rom_service &_rom_service;
- Parent_services &_parent_services;
- Family_member &_family_member;
- Parent_exit *_parent_exit;
- File_descriptor_registry &_file_descriptor_registry;
- Signal_context_capability _destruct_context_cap;
- Pd_session &_ref_pd;
- Pd_session_capability _ref_pd_cap;
- int _exit_value;
- bool _verbose;
-
- template
- static Genode::Service *_find_service(Genode::Registry &services,
- Genode::Service::Name const &name)
- {
- Genode::Service *service = nullptr;
- services.for_each([&] (T &s) {
- if (!service && (s.name() == name))
- service = &s; });
- return service;
- }
-
- /**
- * Find suitable service for a given session request
- *
- * \throw Service_denied
- */
- Service &_matching_service(Service::Name const &service_name,
- Session_label const &label)
- {
- /*
- * Route initial ROM requests (binary and linker) of a forked child
- * to the empty ROM service, since the ROMs are already attached in
- * the replayed region map.
- */
- if (_forked && (service_name == Genode::Rom_session::service_name())) {
- if (label.last_element() == name()) return _empty_rom_service;
- if (label.last_element() == linker_name()) return _empty_rom_service;
- }
-
- Genode::Service *service = nullptr;
-
- /* check for local ROM requests */
- if ((service = _args_policy .resolve_session_request_with_label(service_name, label))
- || (service = _env_policy .resolve_session_request_with_label(service_name, label))
- || (service = _config_policy.resolve_session_request_with_label(service_name, label)))
- return *service;
-
- /* check for local services */
- if (service_name == Genode::Cpu_session::service_name()) return _cpu_service;
- if (service_name == Genode::Rom_session::service_name()) return _rom_service;
- if (service_name == Genode::Pd_session::service_name()) return _pd_service;
- if (service_name == Noux::Session::service_name()) return _noux_service;
-
- /* check for parent services */
- if ((service = _find_service(_parent_services, service_name)))
- return *service;
-
- throw Service_denied();
- }
-
- public:
-
- Child_policy(Name const &name,
- bool forked,
- Dataspace_capability args_ds,
- Dataspace_capability env_ds,
- Dataspace_capability config_ds,
- Rpc_entrypoint &entrypoint,
- Pd_service &pd_service,
- Cpu_service &cpu_service,
- Noux_service &noux_service,
- Empty_rom_service &empty_rom_service,
- Local_rom_service &rom_service,
- Parent_services &parent_services,
- Family_member &family_member,
- Parent_exit *parent_exit,
- File_descriptor_registry &file_descriptor_registry,
- Signal_context_capability destruct_context_cap,
- Pd_session &ref_pd,
- Pd_session_capability ref_pd_cap,
- bool verbose)
- :
- _name(name), _forked(forked),
- _args_policy( "args", args_ds, &entrypoint),
- _env_policy( "env", env_ds, &entrypoint),
- _config_policy("config", config_ds, &entrypoint),
- _pd_service(pd_service),
- _cpu_service(cpu_service),
- _noux_service(noux_service),
- _empty_rom_service(empty_rom_service),
- _rom_service(rom_service),
- _parent_services(parent_services),
- _family_member(family_member),
- _parent_exit(parent_exit),
- _file_descriptor_registry(file_descriptor_registry),
- _destruct_context_cap(destruct_context_cap),
- _ref_pd (ref_pd), _ref_pd_cap (ref_pd_cap),
- _exit_value(~0),
- _verbose(verbose)
- { }
-
- int exit_value() const { return _exit_value; }
-
- /****************************
- ** Child policy interface **
- ****************************/
-
- Name name() const override { return _name; }
-
- Pd_session &ref_pd() override { return _ref_pd; }
- Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
-
- void init(Pd_session &session, Pd_session_capability) override
- {
- session.ref_account(_ref_pd_cap);
- }
-
- Route resolve_session_request(Service::Name const &service_name,
- Session_label const &label) override
- {
- return Route { .service = _matching_service(service_name, label),
- .label = label,
- .diag = Session::Diag() };
- }
-
- void exit(int exit_value) override
- {
- _exit_value = exit_value;
-
- if (_verbose || (exit_value != 0))
- log("child ", _name, " exited with exit value ", exit_value);
-
- /*
- * Close all open file descriptors. This is necessary to unblock
- * the parent if it is trying to read from a pipe (connected to
- * the child) before calling 'wait4()'.
- */
- _file_descriptor_registry.flush();
-
- _family_member.exit(exit_value);
-
- /* notify the parent */
- if (_parent_exit)
- _parent_exit->exit_child();
- else {
- /* handle exit of the init process */
- Signal_transmitter(_destruct_context_cap).submit();
- }
- }
-
- Region_map *address_space(Pd_session &pd) override
- {
- return &static_cast(pd).address_space_region_map();
- }
-
- bool forked() const override { return _forked; }
-};
-
-#endif /* _NOUX__CHILD_POLICY_H_ */
diff --git a/repos/ports/src/noux/cpu_session_component.h b/repos/ports/src/noux/cpu_session_component.h
deleted file mode 100644
index 6435c9ce21..0000000000
--- a/repos/ports/src/noux/cpu_session_component.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * \brief CPU session provided to Noux processes
- * \author Norman Feske
- * \date 2012-02-22
- *
- * The custom implementation of the CPU session interface is used to tweak
- * the startup procedure as performed by the 'Process' class. Normally,
- * processes start execution immediately at creation time at the ELF entry
- * point. For implementing fork semantics, however, this default behavior
- * does not work. Instead, we need to defer the start of the main thread
- * until we have finished copying the address space of the forking process.
- * Furthermore, we need to start the main thread at a custom trampoline
- * function rather than at the ELF entry point. Those customizations are
- * possible by wrapping core's CPU service.
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__CPU_SESSION_COMPONENT_H_
-#define _NOUX__CPU_SESSION_COMPONENT_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-
-/* Noux includes */
-#include
-
-namespace Noux {
- class Cpu_session_component;
- using namespace Genode;
-}
-
-
-class Noux::Cpu_session_component : public Rpc_object
-{
- private:
-
- Rpc_entrypoint &_ep;
- bool const _forked;
- Cpu_connection _cpu;
-
- enum { MAX_THREADS = 8, MAIN_THREAD_IDX = 0 };
-
- Thread_capability _threads[MAX_THREADS];
- Dataspace_capability _trace_control { };
- Dataspace_registry &_registry;
-
- Constructible _ds_info { };
-
- public:
-
- /**
- * Constructor
- *
- * \param forked false if the CPU session belongs to a child
- * created via execve or to the init process, or
- * true if the CPU session belongs to a newly
- * forked process.
- *
- * The 'forked' parameter controls the policy applied to the
- * startup of the main thread.
- */
- Cpu_session_component(Env &env,
- Rpc_entrypoint &ep,
- Child_policy::Name const &label,
- bool forked,
- Dataspace_registry ®istry)
- :
- _ep(ep), _forked(forked), _cpu(env, label.string()), _registry(registry)
- {
- _ep.manage(this);
- }
-
- ~Cpu_session_component()
- {
- _ep.dissolve(this);
-
- if (!_trace_control.valid())
- return;
- }
-
- /**
- * Explicitly start main thread, only meaningful when
- * 'forked' is true
- */
- void start_main_thread(addr_t ip, addr_t sp)
- {
- Capability main_thread = _threads[MAIN_THREAD_IDX];
- Cpu_thread_client(main_thread).start(ip, sp);
- }
-
- Cpu_session_capability cpu_cap() { return _cpu.cap(); }
-
-
- /***************************
- ** Cpu_session interface **
- ***************************/
-
- Thread_capability create_thread(Capability pd_cap,
- Name const &name,
- Affinity::Location affinity,
- Weight weight,
- addr_t utcb) override
- {
- /* create thread at core, keep local copy (needed on NOVA) */
- for (unsigned i = 0; i < MAX_THREADS; i++) {
- if (_threads[i].valid())
- continue;
-
- auto lambda = [&] (Pd_session_component *pd)
- {
- if (!pd)
- throw Thread_creation_failed();
-
- return _cpu.create_thread(pd->core_pd_cap(), name,
- affinity, weight, utcb);
- };
-
- Thread_capability cap = _ep.apply(pd_cap, lambda);
- _threads[i] = cap;
- return cap;
- }
-
- error("maximum number of threads per session reached");
- throw Thread_creation_failed();
- }
-
- void kill_thread(Thread_capability thread) override
- {
- /* purge local copy of thread capability */
- for (unsigned i = 0; i < MAX_THREADS; i++)
- if (_threads[i].local_name() == thread.local_name())
- _threads[i] = Thread_capability();
-
- _cpu.kill_thread(thread);
- }
-
- void exception_sigh(Signal_context_capability handler) override {
- _cpu.exception_sigh(handler); }
-
- Affinity::Space affinity_space() const override {
- return _cpu.affinity_space(); }
-
- Dataspace_capability trace_control() override
- {
- if (!_trace_control.valid()) {
- _trace_control = _cpu.trace_control();
- _ds_info.construct(_registry, _trace_control);
- }
- return _trace_control;
- }
-
- Quota quota() override { return _cpu.quota(); }
-
- int ref_account(Cpu_session_capability c) override {
- return _cpu.ref_account(c); }
-
- int transfer_quota(Cpu_session_capability c, size_t q) override {
- return _cpu.transfer_quota(c, q); }
-
- Capability native_cpu() override {
- return _cpu.native_cpu(); }
-};
-
-#endif /* _NOUX__CPU_SESSION_COMPONENT_H_ */
diff --git a/repos/ports/src/noux/dataspace_registry.h b/repos/ports/src/noux/dataspace_registry.h
deleted file mode 100644
index 3c02eeb703..0000000000
--- a/repos/ports/src/noux/dataspace_registry.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * \brief Registry for dataspaces used by noux processes
- * \author Norman Feske
- * \date 2012-02-22
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__DATASPACE_REGISTRY_H_
-#define _NOUX__DATASPACE_REGISTRY_H_
-
-/* Genode includes */
-#include
-#include
-
-namespace Noux {
- class Dataspace_user;
- class Dataspace_info;
- class Dataspace_registry;
-
- struct Static_dataspace_info;
-
- using namespace Genode;
-}
-
-
-struct Noux::Dataspace_user : Interface, private List::Element
-{
- friend class Dataspace_info;
- friend class List;
-
- virtual void dissolve(Dataspace_info &ds) = 0;
-};
-
-
-class Noux::Dataspace_info : public Object_pool::Entry
-{
- private:
-
- size_t _size;
- Dataspace_capability _ds_cap;
- Lock _users_lock { };
- List _users { };
-
- public:
-
- Dataspace_info(Dataspace_capability ds_cap)
- :
- Object_pool::Entry(ds_cap),
- _size(ds_cap.valid() ? Dataspace_client(ds_cap).size() : 0),
- _ds_cap(ds_cap)
- { }
-
- virtual ~Dataspace_info() { }
-
- size_t size() const { return _size; }
- Dataspace_capability ds_cap() const { return _ds_cap; }
-
- void register_user(Dataspace_user &user)
- {
- Lock::Guard guard(_users_lock);
- _users.insert(&user);
- }
-
- void unregister_user(Dataspace_user &user)
- {
- Lock::Guard guard(_users_lock);
- _users.remove(&user);
- }
-
- void dissolve_users()
- {
- for (;;) {
- Dataspace_user *user = 0;
- {
- Lock::Guard guard(_users_lock);
- user = _users.first();
- if (!user)
- break;
-
- _users.remove(user);
- }
- user->dissolve(*this);
- }
- }
-
- /**
- * Create shadow copy of dataspace
- *
- * \param ram backing store used for copied dataspaces
- * \param local_rm region map used for temporarily attaching
- * dataspaces to the local address space
- * \param alloc allocator used for creatng new 'Dataspace_info'
- * objects
- * \param ds_registry registry for keeping track of
- * the new dataspace
- * \param ep entrypoint used to serve the RPC
- * interface of the new dataspace
- * (used if the dataspace is a sub
- * RM session)
- * \return capability for the new dataspace
- */
- virtual Dataspace_capability fork(Ram_allocator &ram,
- Region_map &local_rm,
- Allocator &alloc,
- Dataspace_registry &ds_registry,
- Rpc_entrypoint &ep) = 0;
-
- /**
- * Write raw byte sequence into dataspace
- *
- * \param local_rm region map used for temporarily attaching
- * the targeted dataspace to the local address
- * space
- * \param dst_offset destination offset within dataspace
- * \param src data source buffer
- * \param len length of source buffer in bytes
- */
- virtual void poke(Region_map &local_rm, addr_t dst_offset,
- char const *src, size_t len) = 0;
-
- /**
- * Return leaf region map that covers a given address
- *
- * \param addr address that is covered by the requested region map
- */
- virtual Capability lookup_region_map(addr_t)
- {
- /* by default a dataspace is no sub region map, so return invalid */
- return Capability();
- }
-};
-
-
-class Noux::Dataspace_registry : public Object_pool
-{
- private:
-
- Allocator &_alloc;
-
- public:
-
- Dataspace_registry(Allocator &alloc) : _alloc(alloc) { }
-
- ~Dataspace_registry()
- {
- /*
- * At the time the destructor is called, most 'Dataspace_info'
- * objects are expected to be gone already because
- * 'Child::_resources' and 'Child::_child' are destructed
- * before the 'Child::_ds_registry'. However, RM dataspaces
- * created via 'Rm_dataspace_info::fork', are not handled by
- * those destructors. So we have to clean them up here.
- */
- remove_all([&] (Dataspace_info *info) { destroy(_alloc, info); });
- }
-};
-
-
-struct Noux::Static_dataspace_info : Dataspace_info
-{
- Dataspace_registry &_ds_registry;
-
- Static_dataspace_info(Dataspace_registry &ds_registry,
- Dataspace_capability ds)
- : Dataspace_info(ds), _ds_registry(ds_registry)
- {
- _ds_registry.insert(this);
- }
-
- ~Static_dataspace_info()
- {
- auto lambda = [this] (Static_dataspace_info *info) {
-
- if (!info) {
- error("lookup of binary ds info failed");
- return;
- }
-
- _ds_registry.remove(info);
-
- info->dissolve_users();
- };
- _ds_registry.apply(ds_cap(), lambda);
- }
-
- Dataspace_capability fork(Ram_allocator &,
- Region_map &,
- Allocator &,
- Dataspace_registry &,
- Rpc_entrypoint &) override
- {
- return ds_cap();
- }
-
- void poke(Region_map &, addr_t, char const *, size_t) override
- {
- error("attempt to poke onto a static dataspace");
- }
-};
-
-#endif /* _NOUX__DATASPACE_REGISTRY_H_ */
diff --git a/repos/ports/src/noux/destruct_queue.h b/repos/ports/src/noux/destruct_queue.h
deleted file mode 100644
index 084878f88b..0000000000
--- a/repos/ports/src/noux/destruct_queue.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * \brief Queue for delayed object destruction
- * \author Christian Prochaska
- * \date 2013-01-03
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__DESTRUCT_QUEUE_H_
-#define _NOUX__DESTRUCT_QUEUE_H_
-
-/* Genode includes */
-#include
-#include
-
-namespace Noux { class Destruct_queue; }
-
-
-class Noux::Destruct_queue
-{
- public:
-
- struct Element_base : Interface, private Genode::List::Element
- {
- friend class List;
- virtual void destroy() = 0;
- };
-
- /*
- * When a pointer to an object which inherits 'Element' among other
- * base classes gets static-casted to a pointer to the 'Element'
- * base object, the resulting address can differ from the start
- * address of the inherited object. To be able to pass the start
- * address of the inherited object to the allocator, a static-cast
- * back to the inherited class needs to be performed. Therefore the
- * type of the class inheriting from 'Element' needs to be given as
- * template parameter.
- */
- template
- class Element : public Element_base
- {
- private:
-
- Genode::Allocator &_alloc;
-
- public:
-
- /**
- * Constructor
- *
- * \param alloc the allocator which was used to allocate
- * the element
- */
- Element(Genode::Allocator &alloc) : _alloc(alloc) { }
-
- virtual ~Element() { };
-
- void destroy() override
- {
- Genode::destroy(_alloc, static_cast(this));
- }
- };
-
- private:
-
- Genode::List _destruct_list { };
- Genode::Lock _destruct_list_lock { };
- Signal_context_capability _sigh;
-
- public:
-
- Destruct_queue(Signal_context_capability sigh) : _sigh(sigh) { }
-
- void insert(Element_base *element)
- {
- Genode::Lock::Guard guard(_destruct_list_lock);
- _destruct_list.insert(element);
-
- Signal_transmitter(_sigh).submit();
- }
-
- void flush()
- {
- Genode::Lock::Guard guard(_destruct_list_lock);
-
- Element_base *element;
- while ((element = _destruct_list.first())) {
- _destruct_list.remove(element);
- element->destroy();
- }
- }
-};
-
-#endif /* _NOUX__DESTRUCT_QUEUE_H_ */
diff --git a/repos/ports/src/noux/empty_rom_service.h b/repos/ports/src/noux/empty_rom_service.h
deleted file mode 100644
index 79ce17a4fd..0000000000
--- a/repos/ports/src/noux/empty_rom_service.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * \brief ROM service provided to Noux processes for initial ROMs
- * \author Christian Prochaska
- * \date 2017-01-31
- *
- * The initial ROMs (binary and linker) are already attached in a forked
- * child and don't need a new ROM dataspace.
- */
-
-/*
- * Copyright (C) 2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU General Public License version 2.
- */
-
-#ifndef _NOUX__EMPTY_ROM_SERVICE_H_
-#define _NOUX__EMPTY_ROM_SERVICE_H_
-
-/* Genode includes */
-#include
-
-/* Noux includes */
-#include
-
-namespace Noux {
-
- typedef Local_service Empty_rom_service;
- class Empty_rom_factory;
-}
-
-
-class Noux::Empty_rom_factory : public Empty_rom_service::Factory
-{
- private:
-
- Allocator &_alloc;
- Rpc_entrypoint &_ep;
-
- public:
-
- Empty_rom_factory(Allocator &alloc, Rpc_entrypoint &ep)
- : _alloc(alloc), _ep(ep) { }
-
- Empty_rom_session_component &create(Args const &, Affinity) override
- {
- try {
- return *new (_alloc) Empty_rom_session_component(_ep); }
- catch (Rom_connection::Rom_connection_failed) {
- throw Service_denied(); }
- }
-
- void upgrade(Empty_rom_session_component &, Args const &) override { }
-
- void destroy(Empty_rom_session_component &session) override
- {
- Genode::destroy(_alloc, &session);
- }
-};
-
-#endif /* _NOUX__EMPTY_ROM_SERVICE_H_ */
diff --git a/repos/ports/src/noux/empty_rom_session_component.h b/repos/ports/src/noux/empty_rom_session_component.h
deleted file mode 100644
index ae5cf82abb..0000000000
--- a/repos/ports/src/noux/empty_rom_session_component.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * \brief ROM session implementation used by Noux processes for initial ROMs
- * \author Christian Prochaska
- * \date 2017-01-31
- *
- * The initial ROMs (binary and linker) are already attached in a forked
- * child and don't need a new ROM dataspace. The invalid dataspace returned
- * by this component is handled in 'Child::Process'.
- */
-
-/*
- * Copyright (C) 2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU General Public License version 2.
- */
-
-#ifndef _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_
-#define _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_
-
-/* Genode includes */
-#include
-
-namespace Noux { class Empty_rom_session_component; }
-
-class Noux::Empty_rom_session_component : public Rpc_object
-{
- private:
-
- Rpc_entrypoint &_ep;
-
- public:
-
- Empty_rom_session_component(Rpc_entrypoint &ep)
- : _ep(ep)
- {
- _ep.manage(this);
- }
-
- ~Empty_rom_session_component()
- {
- _ep.dissolve(this);
- }
-
-
- /***************************
- ** ROM session interface **
- ***************************/
-
- Rom_dataspace_capability dataspace() override
- {
- return Rom_dataspace_capability();
- }
-
- void sigh(Signal_context_capability) override { }
-};
-
-#endif /* _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ */
diff --git a/repos/ports/src/noux/environment.h b/repos/ports/src/noux/environment.h
deleted file mode 100644
index 98da6c7e42..0000000000
--- a/repos/ports/src/noux/environment.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * \brief Process environment utility
- * \author Norman Feske
- * \date 2011-02-17
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__ENVIRONMENT_H_
-#define _NOUX__ENVIRONMENT_H_
-
-/* Genode includes */
-#include
-#include
-
-/* Noux includes */
-#include
-
-namespace Noux {
- class Environment;
- using namespace Genode;
-}
-
-
-class Noux::Environment : Noncopyable
-{
- private:
-
- Attached_ram_dataspace _ds;
-
- Sysio::Env &_env { *_ds.local_addr() };
-
- public:
-
- /**
- * Constructor
- *
- * \param env comma-separated list of environment variables
- */
- Environment(Ram_allocator &ram, Region_map &local_rm, Sysio::Env const &env)
- : _ds(ram, local_rm, sizeof(Sysio::Env))
- {
- memcpy(&_env, &env, sizeof(Sysio::Env));
- }
-
- Dataspace_capability cap() { return _ds.cap(); }
-
- /**
- * Return list of environment variables as zero-separated list
- */
- Sysio::Env const &env() { return _env; }
-};
-
-#endif /* _NOUX__ENVIRONMENT_H_ */
diff --git a/repos/ports/src/noux/family_member.h b/repos/ports/src/noux/family_member.h
deleted file mode 100644
index 1d00d0b018..0000000000
--- a/repos/ports/src/noux/family_member.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * \brief Helper for handling the relationship between Noux processes
- * \author Norman Feske
- * \date 2012-02-25
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__FAMILY_MEMBER_H_
-#define _NOUX__FAMILY_MEMBER_H_
-
-/* Genode includes */
-#include
-#include
-
-/* Noux includes */
-#include
-#include
-
-namespace Noux { class Family_member; }
-
-
-class Noux::Family_member : private List::Element,
- public Parent_exit,
- public Parent_execve
-{
- private:
-
- friend class List;
-
- int const _pid;
- Lock _lock { };
- List _list { };
- bool _has_exited { false };
- int _exit_status { 0 };
-
- protected:
-
- /**
- * Lock used for implementing blocking syscalls,
- * i.e., select, wait4, ...
- */
- Lock _blocker { };
-
- public:
-
- Family_member(int pid) : _pid(pid) { }
-
- virtual ~Family_member() { }
-
- int pid() const { return _pid; }
-
- int exit_status() const { return _exit_status; }
-
- /**
- * Called by the parent at creation time of the process
- */
- void insert(Family_member *member)
- {
- Lock::Guard guard(_lock);
- _list.insert(member);
- }
-
- /**
- * Called by the parent from the return path of the wait4 syscall
- */
- void remove(Family_member *member)
- {
- Lock::Guard guard(_lock);
- _list.remove(member);
- }
-
- virtual void submit_signal(Noux::Sysio::Signal sig) = 0;
-
- /**
- * Called by the parent (originates from Kill_broadcaster)
- */
- bool deliver_kill(int pid, Noux::Sysio::Signal sig)
- {
- Lock::Guard guard(_lock);
-
- if (pid == _pid) {
- submit_signal(sig);
- return true;
- }
-
- bool result = false;
-
- for (Family_member *child = _list.first(); child; child = child->next())
- if (child->deliver_kill(pid, sig))
- result = true;
-
- return result;
- }
-
- /**
- * Parent_exit interface
- */
-
- /* Called by the child on the parent (via Parent_exit) */
- void exit_child() override
- {
- submit_signal(Sysio::Signal::SIG_CHLD);
- }
-
- /**
- * Parent_execve interface
- */
-
- /* Called by the parent from 'execve_child()' */
- virtual Family_member *do_execve(const char *filename,
- Args const &args,
- Sysio::Env const &env) = 0;
-
- /* Called by the child on the parent (via Parent_execve) */
- void execve_child(Family_member &child,
- const char *filename,
- Args const &args,
- Sysio::Env const &env) override
- {
- Lock::Guard guard(_lock);
- Family_member *new_child = child.do_execve(filename,
- args,
- env);
- _list.insert(new_child);
- _list.remove(&child);
- }
-
-
- /**
- * Tell the parent that we exited
- */
- void exit(int exit_status)
- {
- _exit_status = exit_status;
- _has_exited = true;
- }
-
- Family_member *poll4()
- {
- Lock::Guard guard(_lock);
-
- /* check if any of our children has exited */
- Family_member *curr = _list.first();
- for (; curr; curr = curr->next()) {
- if (curr->_has_exited)
- return curr;
- }
- return 0;
- }
-
- /**
- * Wait for the exit of any of our children
- */
- Family_member *wait4()
- {
- /* reset the blocker lock to the 'locked' state */
- _blocker.unlock();
- _blocker.lock();
-
- Family_member *result = poll4();
- if (result)
- return result;
-
- _blocker.lock();
-
- /* either a child exited or a signal occurred */
- return poll4();
- }
-};
-
-#endif /* _NOUX__FAMILY_MEMBER_H_ */
diff --git a/repos/ports/src/noux/file_descriptor_registry.h b/repos/ports/src/noux/file_descriptor_registry.h
deleted file mode 100644
index e698152c1d..0000000000
--- a/repos/ports/src/noux/file_descriptor_registry.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * \brief Manager for file descriptors of one child
- * \author Norman Feske
- * \date 2011-02-17
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__FILE_DESCRIPTOR_REGISTRY_H_
-#define _NOUX__FILE_DESCRIPTOR_REGISTRY_H_
-
-/* Noux includes */
-#include
-
-namespace Noux { class File_descriptor_registry; }
-
-
-class Noux::File_descriptor_registry
-{
- public:
-
- enum { MAX_FILE_DESCRIPTORS = 64 };
-
- private:
-
- struct {
- bool allocated;
- bool close_on_execve;
- Shared_pointer io_channel;
- } _fds[MAX_FILE_DESCRIPTORS] { };
-
- bool _valid_fd(int fd) const
- {
- return (fd >= 0) && (fd < MAX_FILE_DESCRIPTORS);
- }
-
- bool _find_available_fd(int *fd) const
- {
- /* allocate the first free file descriptor */
- for (unsigned i = 0; i < MAX_FILE_DESCRIPTORS; i++)
- if (_fds[i].allocated == false) {
- *fd = i;
- return true;
- }
- return false;
- }
-
- void _assign_fd(int fd, Shared_pointer &io_channel)
- {
- _fds[fd].io_channel = io_channel;
- _fds[fd].allocated = true;
- _fds[fd].close_on_execve = false;
- }
-
- void _reset_fd(int fd)
- {
- _fds[fd].io_channel = Shared_pointer();
- _fds[fd].allocated = false;
- _fds[fd].close_on_execve = false;
- }
-
- public:
-
- File_descriptor_registry()
- {
- flush();
- }
-
- virtual ~File_descriptor_registry() { }
-
- /**
- * Associate I/O channel with file descriptor
- *
- * \return noux file descriptor used for the I/O channel
- */
- virtual int add_io_channel(Shared_pointer io_channel, int fd = -1)
- {
- if ((fd == -1) && !_find_available_fd(&fd)) {
- error("could not allocate file descriptor");
- return -1;
- }
-
- if (!_valid_fd(fd)) {
- error("file descriptor ", fd, " is out of range");
- return -2;
- }
-
- _assign_fd(fd, io_channel);
- return fd;
- }
-
- virtual void remove_io_channel(int fd)
- {
- if (!_valid_fd(fd))
- error("file descriptor ", fd, " is out of range");
- else
- _reset_fd(fd);
- }
-
- bool fd_in_use(int fd) const
- {
- return (_valid_fd(fd) && _fds[fd].io_channel);
- }
-
- Shared_pointer io_channel_by_fd(int fd) const
- {
- if (!fd_in_use(fd))
- return Shared_pointer();
-
- return _fds[fd].io_channel;
- }
-
- void close_fd_on_execve(int fd, bool close_on_execve)
- {
- if (!_valid_fd(fd))
- error("file descriptor ", fd, " is out of range");
- else
- _fds[fd].close_on_execve = close_on_execve;
- }
-
- bool close_fd_on_execve(int fd)
- {
- if (!_valid_fd(fd)) {
- error("file descriptor ", fd, " is out of range");
- return false;
- }
-
- return _fds[fd].close_on_execve;
- }
-
- virtual void flush()
- {
- /* close all file descriptors */
- for (unsigned i = 0; i < MAX_FILE_DESCRIPTORS; i++)
- _reset_fd(i);
- }
-};
-
-#endif /* _NOUX__FILE_DESCRIPTOR_REGISTRY_H_ */
diff --git a/repos/ports/src/noux/interrupt_handler.h b/repos/ports/src/noux/interrupt_handler.h
deleted file mode 100644
index 86132e89eb..0000000000
--- a/repos/ports/src/noux/interrupt_handler.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * \brief Interrupt handler interface
- * \author Christian Prochaska
- * \date 2013-10-08
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__INTERRUPT_HANDLER__H_
-#define _NOUX__INTERRUPT_HANDLER__H_
-
-#include
-
-namespace Noux {
-
- struct Interrupt_handler : Genode::Interface
- {
- virtual void handle_interrupt(Sysio::Signal) = 0;
- };
-};
-
-#endif /* _NOUX__INTERRUPT_HANDLER__H_ */
-
diff --git a/repos/ports/src/noux/io_channel.h b/repos/ports/src/noux/io_channel.h
deleted file mode 100644
index 02e625d753..0000000000
--- a/repos/ports/src/noux/io_channel.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * \brief I/O channel
- * \author Norman Feske
- * \date 2011-02-17
- *
- * An 'Io_channel' is the interface for the operations on an open file
- * descriptor.
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__IO_CHANNEL_H_
-#define _NOUX__IO_CHANNEL_H_
-
-/* Genode includes */
-#include
-#include
-
-/* Noux includes */
-#include
-#include
-#include
-#include
-
-namespace Noux {
- extern Genode::Lock &signal_lock();
-
- class Io_channel_backend;
- class Io_channel;
-
- class Terminal_io_channel;
-}
-
-
-/**
- * Input/output channel backend that is used for calling
- * different methods, which does not belong to the original
- * interface, e.g. network methods.
- */
-struct Noux::Io_channel_backend
-{
- virtual ~Io_channel_backend() { }
-
- virtual int type() const { return -1; }
-};
-
-
-/**
- * Input/output channel interface
- */
-class Noux::Io_channel : private Reference_counter
-{
- private:
-
- friend class Shared_pointer;
-
- /**
- * List of notifiers (i.e., processes) used by threads that block
- * for an I/O-channel event
- */
- List _notifiers { };
- Lock _notifiers_lock { };
- List _interrupt_handlers { };
- Lock _interrupt_handlers_lock { };
-
- public:
-
- virtual ~Io_channel() { }
-
- virtual Io_channel_backend *backend() { return nullptr; }
-
- virtual bool write(Sysio &) { return false; }
- virtual bool read(Sysio &) { return false; }
- virtual bool fstat(Sysio &) { return false; }
- virtual bool ftruncate(Sysio &) { return false; }
- virtual bool fcntl(Sysio &) { return false; }
- virtual bool dirent(Sysio &) { return false; }
- virtual bool ioctl(Sysio &) { return false; }
- virtual bool lseek(Sysio &) { return false; }
-
- /**
- * Return true if an unblocking condition of the channel is satisfied
- *
- * \param rd if true, check for data available for reading
- * \param wr if true, check for readiness for writing
- * \param ex if true, check for exceptions
- */
- virtual bool check_unblock(bool /* rd */, bool /* wr */, bool /* ex */) const {
- return false; }
-
- /**
- * Return true if the channel is set to non-blocking mode
- */
- virtual bool nonblocking() { return false; }
-
- /**
- * Register blocker for getting waked up on an I/O channel event
- *
- * This function is normally called by the to-be-blocked thread
- * prior blocking itself, e.g., during a 'select' syscall.
- */
- void register_wake_up_notifier(Wake_up_notifier *notifier)
- {
- Lock::Guard guard(_notifiers_lock);
-
- _notifiers.insert(notifier);
- }
-
- /**
- * Unregister wake-up notifier
- *
- * This function is normally called after a blocker has left the
- * blocking condition, e.g., during the return from the 'select'
- * syscall'.
- */
- void unregister_wake_up_notifier(Wake_up_notifier *notifier)
- {
- Lock::Guard guard(_notifiers_lock);
-
- _notifiers.remove(notifier);
- }
-
- /**
- * Tell all registered notifiers about an occurred I/O event
- *
- * This function is called by I/O channel implementations that
- * respond to external signals, e.g., the availability of new
- * input from a terminal session.
- */
- void invoke_all_notifiers()
- {
- Lock::Guard guard(_notifiers_lock);
-
- for (Wake_up_notifier *n = _notifiers.first(); n; n = n->next())
- n->wake_up();
- }
-
- /**
- * Register interrupt handler
- *
- * This function is called by Child objects to get woken up if the
- * terminal sends, for example, Ctrl-C.
- */
- void register_interrupt_handler(Io_channel_listener *handler)
- {
- Lock::Guard guard(_interrupt_handlers_lock);
-
- _interrupt_handlers.insert(handler);
- }
-
- /**
- * Unregister interrupt handler
- */
- void unregister_interrupt_handler(Io_channel_listener *handler)
- {
- Lock::Guard guard(_interrupt_handlers_lock);
-
- _interrupt_handlers.remove(handler);
- }
-
- /**
- * Find the 'Io_channel_listener' object which contains the given
- * 'Interrupt_handler' pointer
- */
- Io_channel_listener *lookup_io_channel_listener(Interrupt_handler *handler)
- {
- for (Io_channel_listener *l = _interrupt_handlers.first();
- l; l = l->next())
- if (l->object() == handler)
- return l;
- return 0;
- }
-
- /**
- * Tell all registered handlers about an interrupt event
- */
- void invoke_all_interrupt_handlers(Sysio::Signal signal)
- {
- Lock::Guard signal_lock_guard(signal_lock());
- Lock::Guard guard(_interrupt_handlers_lock);
-
- for (Io_channel_listener *l = _interrupt_handlers.first();
- l; l = l->next())
- l->object()->handle_interrupt(signal);
- }
-
- /**
- * Get the path of the file associated with the I/O channel
- *
- * This function is used to simplify the implemenation of SYSCALL_FSTAT
- * and is only implemented by Vfs_io_channel.
- */
- virtual bool path(char * /* path */, size_t /* len */) { return false; }
-};
-
-#endif /* _NOUX__IO_CHANNEL_H_ */
diff --git a/repos/ports/src/noux/io_channel_listener.h b/repos/ports/src/noux/io_channel_listener.h
deleted file mode 100644
index c80dadb780..0000000000
--- a/repos/ports/src/noux/io_channel_listener.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * \brief IO channel listener
- * \author Christian Prochaska
- * \date 2014-01-23
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__IO_CHANNEL_LISTENER__H_
-#define _NOUX__IO_CHANNEL_LISTENER__H_
-
-/* Genode includes */
-#include
-
-/* Noux includes */
-#include
-
-namespace Noux { typedef List_element Io_channel_listener; }
-
-#endif /* _NOUX__IO_CHANNEL_LISTENER__H_ */
-
diff --git a/repos/ports/src/noux/io_receptor_registry.h b/repos/ports/src/noux/io_receptor_registry.h
deleted file mode 100644
index 7277028479..0000000000
--- a/repos/ports/src/noux/io_receptor_registry.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * \brief Io receptor registry
- * \author Josef Soentgen
- * \date 2012-10-05
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__IO_RECEPTOR_REGISTRY_H_
-#define _NOUX__IO_RECEPTOR_REGISTRY_H_
-
-/* Genode includes */
-#include
-#include
-
-
-namespace Noux {
- struct Io_receptor;
- struct Io_receptor_registry;
-}
-
-
-struct Noux::Io_receptor : List::Element
-{
- private:
-
- Lock *_lock;
-
- public:
-
- Io_receptor(Lock *lock) : _lock(lock) { }
-
- void check_and_wakeup()
- {
- if (_lock)
- _lock->unlock();
- }
-};
-
-
-class Noux::Io_receptor_registry
-{
- private:
-
- List _receptors { };
- Lock _receptors_lock { };
-
- public:
-
- Io_receptor_registry() { }
-
- ~Io_receptor_registry()
- {
- Io_receptor *receptor;
- while ((receptor = _receptors.first()) != 0)
- _receptors.remove(receptor);
- }
-
- void register_receptor(Io_receptor *receptor)
- {
- Lock::Guard guard(_receptors_lock);
-
- _receptors.insert(receptor);
- }
-
- void unregister_receptor(Io_receptor *receptor)
- {
- Lock::Guard guard(_receptors_lock);
-
- _receptors.remove(receptor);
- }
-
- Io_receptor *first() { return _receptors.first(); }
-};
-
-#endif /* _NOUX__IO_RECEPTOR_REGISTRY_H_ */
diff --git a/repos/ports/src/noux/kill_broadcaster.h b/repos/ports/src/noux/kill_broadcaster.h
deleted file mode 100644
index 91c45a67bf..0000000000
--- a/repos/ports/src/noux/kill_broadcaster.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * \brief Kill_broadcaster interface
- * \author Christian Prochaska
- * \date 2014-01-13
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__KILL_BROADCASTER__H_
-#define _NOUX__KILL_BROADCASTER__H_
-
-/* Noux includes */
-#include
-
-namespace Noux {
-
- struct Kill_broadcaster : Genode::Interface
- {
- virtual bool kill(int pid, Noux::Sysio::Signal sig) = 0;
- };
-};
-
-#endif /* _NOUX__KILL_BROADCASTER__H_ */
-
diff --git a/repos/ports/src/noux/local_rom_service.h b/repos/ports/src/noux/local_rom_service.h
deleted file mode 100644
index ec53a7ad52..0000000000
--- a/repos/ports/src/noux/local_rom_service.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * \brief ROM service provided to Noux processes
- * \author Norman Feske
- * \date 2013-07-18
- *
- * The local ROM service has the sole purpose of tracking ROM dataspaces
- * so that they are properly detached from RM sessions when the corresponding
- * ROM sessions are closed.
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__LOCAL_ROM_SERVICE_H_
-#define _NOUX__LOCAL_ROM_SERVICE_H_
-
-/* Genode includes */
-#include
-
-/* Noux includes */
-#include
-#include
-
-namespace Noux {
-
- typedef Local_service Local_rom_service;
- class Local_rom_factory;
-}
-
-
-class Noux::Local_rom_factory : public Local_rom_service::Factory
-{
- private:
-
- Allocator &_alloc;
- Env &_env;
- Rpc_entrypoint &_ep;
- Vfs::File_system &_root_dir;
- Vfs_io_waiter_registry &_vfs_io_waiter_registry;
- Dataspace_registry &_registry;
-
- public:
-
- Local_rom_factory(Allocator &alloc, Env &env, Rpc_entrypoint &ep,
- Vfs::File_system &root_dir,
- Vfs_io_waiter_registry &vfs_io_waiter_registry,
- Dataspace_registry ®istry)
- :
- _alloc(alloc), _env(env), _ep(ep), _root_dir(root_dir),
- _vfs_io_waiter_registry(vfs_io_waiter_registry),
- _registry(registry)
- { }
-
- Rom_session_component &create(Args const &args, Affinity) override
- {
- try {
- Rom_session_component::Name const rom_name =
- label_from_args(args.string()).last_element();
-
- return *new (_alloc)
- Rom_session_component(_alloc, _env, _ep, _root_dir,
- _vfs_io_waiter_registry, _registry,
- rom_name);
- }
- catch (Rom_connection::Rom_connection_failed) {
- throw Service_denied(); }
- }
-
- void upgrade(Rom_session_component &, Args const &) override { }
-
- void destroy(Rom_session_component &session) override
- {
- Genode::destroy(_alloc, &session);
- }
-};
-
-#endif /* _NOUX__LOCAL_ROM_SERVICE_H_ */
diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc
deleted file mode 100644
index 3fc8b23598..0000000000
--- a/repos/ports/src/noux/main.cc
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * \brief Unix emulation environment for Genode
- * \author Norman Feske
- * \date 2011-02-14
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-
-/* Noux includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace Noux {
-
- static Noux::Child *init_child;
- static int exit_value = ~0;
-
- bool init_process(Child *child) { return child == init_child; }
- void init_process_exited(int exit) { init_child = 0; exit_value = exit; }
-}
-
-
-Noux::Io_receptor_registry * Noux::io_receptor_registry()
-{
- static Noux::Io_receptor_registry _inst;
- return &_inst;
-}
-
-
-/**
- * Return string containing the environment variables of init
- *
- * The variable definitions are separated by zeros. The end of the string is
- * marked with another zero.
- */
-static Noux::Sysio::Env &env_string_of_init_process(Genode::Xml_node config)
-{
- static Noux::Sysio::Env env;
- int index = 0;
-
- /* read environment variables for init process from config */
- Genode::Xml_node start_node = config.sub_node("start");
- try {
- Genode::Xml_node node = start_node.sub_node("env");
- for (; ; node = node.next("env")) {
-
- typedef Genode::String<256> Var;
- Var const var(node.attribute_value("name", Var()), "=",
- node.attribute_value("value", Var()));
-
- bool const env_exeeded = index + var.length() >= sizeof(env);
- bool const var_exeeded = (var.length() == var.capacity());
-
- if (env_exeeded || var_exeeded) {
- warning("truncated environment variable: ", node);
- env[index] = 0;
- break;
- }
-
- Genode::strncpy(&env[index], var.string(), var.length());
- index += var.length();
- }
- }
- catch (Genode::Xml_node::Nonexistent_sub_node) { }
-
- return env;
-}
-
-
-namespace Noux { class Stdio_unavailable : Genode::Exception { }; }
-
-
-/*
- * \throw Stdio_unavailable
- */
-static Noux::Io_channel &
-connect_stdio(Genode::Env &env,
- Genode::Constructible &terminal,
- Genode::Xml_node config,
- Vfs::File_system &root,
- Noux::Vfs_io_waiter_registry &vfs_io_waiter_registry,
- Noux::Terminal_io_channel::Type type,
- Genode::Allocator &alloc,
- Noux::Time_info &time_info,
- Timer::Connection &timer)
-{
- using namespace Vfs;
- using namespace Noux;
- typedef Terminal_io_channel Tio; /* just a local abbreviation */
-
- typedef Genode::String Path;
- Vfs_handle *vfs_handle = nullptr;
- char const *stdio_name = "";
- unsigned mode = 0;
-
- switch (type) {
- case Tio::STDIN:
- stdio_name = "stdin";
- mode = Directory_service::OPEN_MODE_RDONLY;
- break;
- case Tio::STDOUT:
- stdio_name = "stdout";
- mode = Directory_service::OPEN_MODE_WRONLY;
- break;
- case Tio::STDERR:
- stdio_name = "stderr";
- mode = Directory_service::OPEN_MODE_WRONLY;
- break;
- };
-
- if (!config.has_attribute(stdio_name)) {
- if (!terminal.constructed())
- terminal.construct(env);
- warning(stdio_name, " VFS path not defined, connecting to terminal session");
- return *new (alloc) Tio(*terminal, type, env.ep());
- }
-
- Path const path = config.attribute_value(stdio_name, Path());
-
- if (root.open(path.string(), mode, &vfs_handle, alloc)
- != Directory_service::OPEN_OK)
- {
- error("failed to connect ", stdio_name, " to '", path, "'");
- throw Stdio_unavailable();
- }
-
- return *new (alloc)
- Vfs_io_channel(path.string(), root.leaf_path(path.string()),
- vfs_handle, vfs_io_waiter_registry, env.ep(),
- time_info, timer);
-}
-
-
-/*
- * This lock is needed to delay the insertion of signals into a child object.
- * This is necessary during an 'execve()' syscall, when signals get copied from
- * the old child object to the new one. Without the lock, an IO channel could
- * insert a signal into both objects, which could lead to a duplicated signal
- * in the new child object.
- */
-Genode::Lock &Noux::signal_lock()
-{
- static Genode::Lock inst;
- return inst;
-}
-
-
-namespace Noux { struct Main; }
-
-
-struct Noux::Main
-{
- Env &_env;
-
- Heap _heap { _env.ram(), _env.rm() };
-
- /* whitelist of service requests to be routed to the parent */
- Noux::Parent_services _parent_services { };
-
- Noux::Parent_service _log_parent_service { _parent_services, _env, "LOG" };
- Noux::Parent_service _timer_parent_service { _parent_services, _env, "Timer" };
-
- Attached_rom_dataspace _config { _env, "config" };
-
- Verbose _verbose { _config.xml() };
-
- /**
- * Return name of init process as specified in the config
- */
- Child_policy::Name _name_of_init_process() const
- {
- return _config.xml().sub_node("start").attribute_value("name", Child_policy::Name());
- }
-
- /**
- * Read command-line arguments of init process from config
- */
- Args const &_args_of_init_process()
- {
- static char args_buf[4096];
- static Args args(args_buf, sizeof(args_buf));
-
- Xml_node start_node = _config.xml().sub_node("start");
- try {
- /* the first argument is the program name */
- args.append(_name_of_init_process().string());
-
- start_node.for_each_sub_node("arg", [&] (Xml_node arg_node) {
- typedef String<512> Value;
- args.append(arg_node.attribute_value("value", Value()).string());
- });
-
- } catch (Args::Overrun) { error("argument buffer overrun"); }
-
- return args;
- }
-
- /* initialize virtual file system */
- Vfs::Global_file_system_factory _global_file_system_factory { _heap };
-
- struct Io_progress_handler : Genode::Entrypoint::Io_progress_handler
- {
- Vfs_io_waiter_registry io_waiter_registry { };
-
- Io_progress_handler(Genode::Entrypoint &ep)
- {
- ep.register_io_progress_handler(*this);
- }
-
- void handle_io_progress() override
- {
- io_waiter_registry.for_each([] (Vfs_io_waiter &r) {
- r.wakeup();
- });
- }
-
- } _io_response_handler { _env.ep() };
-
- Vfs::Simple_env _vfs_env { _env, _heap, _config.xml().sub_node("fstab") };
-
- Vfs::File_system &_root_dir = _vfs_env.root_dir();
-
- Pid_allocator _pid_allocator { };
-
- Timer::Connection _timer_connection { _env };
-
- User_info _user_info { _config.xml() };
-
- Time_info _time_info { _env, _config.xml() };
-
- Signal_handler _destruct_handler {
- _env.ep(), *this, &Main::_handle_destruct };
-
- Destruct_queue _destruct_queue { _destruct_handler };
-
- void _handle_destruct()
- {
- _destruct_queue.flush();
-
- /* let noux exit if the init process exited */
- if (!init_child) {
- _channel_0 = Shared_pointer();
- _channel_1 = Shared_pointer();
- _channel_2 = Shared_pointer();
- _env.parent().exit(exit_value);
- }
- }
-
- struct Kill_broadcaster_impl: Kill_broadcaster
- {
- Family_member *init_process = nullptr;
-
- bool kill(int pid, Noux::Sysio::Signal sig) override
- {
- return init_process->deliver_kill(pid, sig);
- }
-
- } _kill_broadcaster { };
-
- Noux::Child _init_child { _name_of_init_process(),
- _verbose,
- _user_info,
- _time_info,
- 0,
- _kill_broadcaster,
- _timer_connection,
- _init_child,
- _pid_allocator,
- _pid_allocator.alloc(),
- _env,
- _root_dir,
- _io_response_handler.io_waiter_registry,
- _args_of_init_process(),
- env_string_of_init_process(_config.xml()),
- _heap,
- _env.pd(),
- _env.pd_session_cap(),
- _parent_services,
- false,
- _destruct_queue };
-
- Constructible _terminal { };
-
- /*
- * I/O channels must be dynamically allocated to handle cases where the
- * init program closes one of these.
- */
- typedef Terminal_io_channel Tio; /* just a local abbreviation */
-
- Shared_pointer
- _channel_0 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
- _io_response_handler.io_waiter_registry,
- Tio::STDIN, _heap, _time_info, _timer_connection), _heap },
- _channel_1 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
- _io_response_handler.io_waiter_registry,
- Tio::STDOUT, _heap, _time_info, _timer_connection), _heap },
- _channel_2 { &connect_stdio(_env, _terminal, _config.xml(), _root_dir,
- _io_response_handler.io_waiter_registry,
- Tio::STDERR, _heap, _time_info, _timer_connection), _heap };
-
- Main(Env &env) : _env(env)
- {
- log("--- noux started ---");
-
- _init_child.add_io_channel(_channel_0, 0);
- _init_child.add_io_channel(_channel_1, 1);
- _init_child.add_io_channel(_channel_2, 2);
-
- _kill_broadcaster.init_process = &_init_child;
-
- init_child = &_init_child;
-
- _init_child.start();
- }
-};
-
-
-void Component::construct(Genode::Env &env)
-{
- static Noux::Main main(env);
-}
diff --git a/repos/ports/src/noux/parent_execve.h b/repos/ports/src/noux/parent_execve.h
deleted file mode 100644
index 6effe1d061..0000000000
--- a/repos/ports/src/noux/parent_execve.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * \brief Parent_execve interface
- * \author Christian Prochaska
- * \date 2014-01-13
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__PARENT_EXECVE__H_
-#define _NOUX__PARENT_EXECVE__H_
-
-/* Noux includes */
-#include
-
-namespace Noux {
- struct Family_member;
- struct Parent_execve;
-}
-
-
-struct Noux::Parent_execve : Genode::Interface
-{
- virtual void execve_child(Family_member &child,
- const char *filename,
- Args const &args,
- Sysio::Env const &env) = 0;
-};
-
-#endif /* _NOUX__PARENT_EXECVE__H_ */
-
diff --git a/repos/ports/src/noux/parent_exit.h b/repos/ports/src/noux/parent_exit.h
deleted file mode 100644
index 0cf6725369..0000000000
--- a/repos/ports/src/noux/parent_exit.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * \brief Parent_exit interface
- * \author Christian Prochaska
- * \date 2014-01-16
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__PARENT_EXIT__H_
-#define _NOUX__PARENT_EXIT__H_
-
-#include
-
-namespace Noux {
-
- struct Family_member;
-
- struct Parent_exit : Genode::Interface
- {
- /*
- * Handle the exiting of a child
- */
-
- virtual void exit_child() = 0;
- };
-
-};
-
-#endif /* _NOUX__PARENT_EXIT__H_ */
-
diff --git a/repos/ports/src/noux/path.h b/repos/ports/src/noux/path.h
deleted file mode 100644
index 752b8eddd6..0000000000
--- a/repos/ports/src/noux/path.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * \brief Path handling utility for Noux
- * \author Norman Feske
- * \date 2011-02-17
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__PATH_H_
-#define _NOUX__PATH_H_
-
-/* Genode includes */
-#include
-
-namespace Noux { using Vfs::Absolute_path; }
-
-#endif /* _NOUX__PATH_H_ */
diff --git a/repos/ports/src/noux/pd_session_component.h b/repos/ports/src/noux/pd_session_component.h
deleted file mode 100644
index 20ce932957..0000000000
--- a/repos/ports/src/noux/pd_session_component.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * \brief PD service used by Noux processes
- * \author Norman Feske
- * \date 2016-04-20
- *
- * The custom implementation of the PD session interface provides a pool of
- * RAM shared by Noux and all Noux processes. The use of a shared pool
- * alleviates the need to assign RAM quota to individual Noux processes.
- *
- * Furthermore, the custom implementation is needed to get hold of the RAM
- * dataspaces allocated by each Noux process. When forking a process, the
- * acquired information (in the form of 'Ram_dataspace_info' objects) is used
- * to create a shadow copy of the forking address space.
- */
-
-/*
- * Copyright (C) 2016-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__PD_SESSION_COMPONENT_H_
-#define _NOUX__PD_SESSION_COMPONENT_H_
-
-/* Genode includes */
-#include
-#include
-#include
-
-/* Noux includes */
-#include
-#include
-
-namespace Noux {
- struct Ram_dataspace_info;
- struct Pd_session_component;
- using namespace Genode;
-}
-
-
-struct Noux::Ram_dataspace_info : Dataspace_info,
- private List::Element
-{
- friend class List;
-
- Ram_dataspace_info(Ram_dataspace_capability ds_cap)
- : Dataspace_info(ds_cap) { }
-
- Dataspace_capability fork(Ram_allocator &ram,
- Region_map &local_rm,
- Allocator &alloc,
- Dataspace_registry &ds_registry,
- Rpc_entrypoint &) override
- {
- size_t const size = Dataspace_client(ds_cap()).size();
- Ram_dataspace_capability dst_ds_cap;
-
- try {
- dst_ds_cap = ram.alloc(size);
-
- Attached_dataspace src_ds(local_rm, ds_cap());
- Attached_dataspace dst_ds(local_rm, dst_ds_cap);
- memcpy(dst_ds.local_addr(), src_ds.local_addr(), size);
-
- ds_registry.insert(new (alloc) Ram_dataspace_info(dst_ds_cap));
- return dst_ds_cap;
-
- } catch (...) {
- error("fork of RAM dataspace failed");
-
- if (dst_ds_cap.valid())
- ram.free(dst_ds_cap);
-
- return Dataspace_capability();
- }
- }
-
- void poke(Region_map &rm, addr_t dst_offset, char const *src, size_t len) override
- {
- if (!src) return;
-
- if ((dst_offset >= size()) || (dst_offset + len > size())) {
- error("illegal attemt to write beyond dataspace boundary");
- return;
- }
-
- try {
- Attached_dataspace ds(rm, ds_cap());
- memcpy(ds.local_addr() + dst_offset, src, len);
- } catch (...) { warning("poke: failed to attach RAM dataspace"); }
- }
-};
-
-
-class Noux::Pd_session_component : public Rpc_object
-{
- private:
-
- Rpc_entrypoint &_ep;
-
- Pd_connection _pd;
-
- Pd_session &_ref_pd;
-
- Region_map_component _address_space;
- Region_map_component _stack_area;
- Region_map_component _linker_area;
-
- Allocator &_alloc;
-
- Ram_allocator &_ram;
-
- Ram_quota _used_ram_quota { 0 };
-
- List _ds_list { };
-
- Dataspace_registry &_ds_registry;
-
- template
- auto _with_automatic_cap_upgrade(FUNC func) -> decltype(func())
- {
- Cap_quota upgrade { 10 };
- enum { NUM_ATTEMPTS = 3 };
- return retry(
- [&] () { return func(); },
- [&] () { _ref_pd.transfer_quota(_pd.rpc_cap(), upgrade); },
- NUM_ATTEMPTS);
- }
-
- public:
-
- /**
- * Constructor
- */
- Pd_session_component(Allocator &alloc, Env &env, Rpc_entrypoint &ep,
- Child_policy::Name const &name,
- Dataspace_registry &ds_registry)
- :
- _ep(ep), _pd(env, name.string()), _ref_pd(env.pd()),
- _address_space(alloc, _ep, ds_registry, _pd, _pd.address_space()),
- _stack_area (alloc, _ep, ds_registry, _pd, _pd.stack_area()),
- _linker_area (alloc, _ep, ds_registry, _pd, _pd.linker_area()),
- _alloc(alloc), _ram(env.ram()), _ds_registry(ds_registry)
- {
- _ep.manage(this);
-
- /*
- * Equip the PD with an initial cap quota that suffices in the
- * common case. Further capabilities are provisioned on demand
- * via '_with_automatic_cap_upgrade'.
- */
- _pd.ref_account(env.pd_session_cap());
- _ref_pd.transfer_quota(_pd.rpc_cap(), Cap_quota{10});
- }
-
- ~Pd_session_component()
- {
- _ep.dissolve(this);
-
- Ram_dataspace_info *info = 0;
- while ((info = _ds_list.first()))
- free(static_cap_cast(info->ds_cap()));
- }
-
- Pd_session_capability core_pd_cap() { return _pd.cap(); }
-
- void poke(Region_map &rm, addr_t dst_addr, char const *src, size_t len)
- {
- _address_space.poke(rm, dst_addr, src, len);
- }
-
- Capability lookup_region_map(addr_t const addr)
- {
- return _address_space.lookup_region_map(addr);
- }
-
- Region_map &address_space_region_map() { return _address_space; }
- Region_map &linker_area_region_map() { return _linker_area; }
- Region_map &stack_area_region_map() { return _stack_area; }
-
- void replay(Pd_session_component &dst_pd,
- Region_map &local_rm,
- Allocator &alloc,
- Dataspace_registry &ds_registry,
- Rpc_entrypoint &ep)
- {
- /* replay region map into new protection domain */
- _stack_area .replay(dst_pd, dst_pd.stack_area_region_map(), local_rm, alloc, ds_registry, ep);
- _linker_area .replay(dst_pd, dst_pd.linker_area_region_map(), local_rm, alloc, ds_registry, ep);
- _address_space.replay(dst_pd, dst_pd.address_space_region_map(), local_rm, alloc, ds_registry, ep);
-
- Region_map &dst_address_space = dst_pd.address_space_region_map();
- Region_map &dst_stack_area = dst_pd.stack_area_region_map();
- Region_map &dst_linker_area = dst_pd.linker_area_region_map();
-
- /* attach stack area */
- dst_address_space.attach(dst_stack_area.dataspace(),
- Dataspace_client(dst_stack_area.dataspace()).size(),
- 0, true,
- _address_space.lookup_region_base(_stack_area.dataspace()));
-
- /* attach linker area */
- dst_address_space.attach(dst_linker_area.dataspace(),
- Dataspace_client(dst_linker_area.dataspace()).size(),
- 0, true,
- _address_space.lookup_region_base(_linker_area.dataspace()), true);
- }
-
-
- /**************************
- ** Pd_session interface **
- **************************/
-
- void assign_parent(Capability parent) override {
- _pd.assign_parent(parent); }
-
- bool assign_pci(addr_t addr, uint16_t bdf) override {
- return _pd.assign_pci(addr, bdf); }
-
- void map(addr_t virt, addr_t size) override {
- return _pd.map(virt, size); }
-
- Signal_source_capability alloc_signal_source() override
- {
- return _with_automatic_cap_upgrade([&] () {
- return _pd.alloc_signal_source(); });
- }
-
- void free_signal_source(Signal_source_capability cap) override {
- _pd.free_signal_source(cap); }
-
- Capability alloc_context(Signal_source_capability source,
- unsigned long imprint) override
- {
- return _with_automatic_cap_upgrade([&] () {
- return _pd.alloc_context(source, imprint); });
- }
-
- void free_context(Capability cap) override {
- _pd.free_context(cap); }
-
- void submit(Capability context, unsigned cnt) override {
- _pd.submit(context, cnt); }
-
- Native_capability alloc_rpc_cap(Native_capability ep) override
- {
- return _with_automatic_cap_upgrade([&] () {
- return _pd.alloc_rpc_cap(ep); });
- }
-
- void free_rpc_cap(Native_capability cap) override {
- _pd.free_rpc_cap(cap); }
-
- Capability address_space() override {
- return _address_space.Rpc_object::cap(); }
-
- Capability stack_area() override {
- return _stack_area.Rpc_object::cap(); }
-
- Capability linker_area() override {
- return _linker_area.Rpc_object::cap(); }
-
- void ref_account(Capability) override { }
-
- void transfer_quota(Capability, Cap_quota) override { }
-
- Cap_quota cap_quota() const override { return _pd.cap_quota(); }
- Cap_quota used_caps() const override { return _pd.used_caps(); }
-
- Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
- {
- Ram_dataspace_capability ds_cap = _ram.alloc(size, cached);
-
- Ram_dataspace_info *ds_info = new (_alloc) Ram_dataspace_info(ds_cap);
-
- _ds_registry.insert(ds_info);
- _ds_list.insert(ds_info);
-
- _used_ram_quota = Ram_quota { _used_ram_quota.value + size };
-
- return ds_cap;
- }
-
- void free(Ram_dataspace_capability ds_cap) override
- {
- Ram_dataspace_info *ds_info;
-
- auto lambda = [&] (Ram_dataspace_info *rdi) {
- ds_info = rdi;
-
- if (!ds_info) {
- error("RAM free: dataspace lookup failed");
- return;
- }
-
- size_t const ds_size = rdi->size();
-
- _ds_registry.remove(ds_info);
- ds_info->dissolve_users();
- _ds_list.remove(ds_info);
- _ram.free(ds_cap);
-
- _used_ram_quota = Ram_quota { _used_ram_quota.value - ds_size };
- };
- _ds_registry.apply(ds_cap, lambda);
- destroy(_alloc, ds_info);
- }
-
- size_t dataspace_size(Ram_dataspace_capability ds_cap) const override
- {
- size_t result = 0;
- _ds_registry.apply(ds_cap, [&] (Ram_dataspace_info *rdi) {
- if (rdi)
- result = rdi->size(); });
- return result;
- }
-
- void transfer_quota(Pd_session_capability, Ram_quota) override { }
- Ram_quota ram_quota() const override { return _pd.ram_quota(); }
- Ram_quota used_ram() const override { return Ram_quota{_used_ram_quota}; }
-
- Capability native_pd() override {
- return _pd.native_pd(); }
-};
-
-#endif /* _NOUX__PD_SESSION_COMPONENT_H_ */
diff --git a/repos/ports/src/noux/pipe_io_channel.h b/repos/ports/src/noux/pipe_io_channel.h
deleted file mode 100644
index 9d7f8d4498..0000000000
--- a/repos/ports/src/noux/pipe_io_channel.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * \brief I/O channels for pipe input/output
- * \author Norman Feske
- * \date 2012-03-19
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__PIPE_IO_CHANNEL_H_
-#define _NOUX__PIPE_IO_CHANNEL_H_
-
-/* Noux includes */
-#include
-
-namespace Noux {
- class Pipe;
- class Pipe_sink_io_channel;
- class Pipe_source_io_channel;
-}
-
-
-class Noux::Pipe : public Reference_counter
-{
- private:
-
- Lock mutable _lock { };
-
- enum { BUFFER_SIZE = 4096 };
- char _buffer[BUFFER_SIZE];
-
- unsigned _read_offset { 0 };
- unsigned _write_offset { 0 };
-
- Signal_context_capability _read_ready_sigh { };
- Signal_context_capability _write_ready_sigh { };
-
- bool _writer_is_gone { false };
-
- /**
- * Return space available in the buffer for writing, in bytes
- */
- size_t _avail_buffer_space() const
- {
- if (_read_offset < _write_offset)
- return (BUFFER_SIZE - _write_offset) + _read_offset - 1;
-
- if (_read_offset > _write_offset)
- return _read_offset - _write_offset - 1;
-
- /* _read_offset == _write_offset */
- return BUFFER_SIZE - 1;
- }
-
- bool _any_space_avail_for_writing() const
- {
- return _avail_buffer_space() > 0;;
- }
-
- void _wake_up_reader()
- {
- if (_read_ready_sigh.valid())
- Signal_transmitter(_read_ready_sigh).submit();
- }
-
- void _wake_up_writer()
- {
- if (_write_ready_sigh.valid())
- Signal_transmitter(_write_ready_sigh).submit();
- }
-
- public:
-
- ~Pipe()
- {
- Lock::Guard guard(_lock);
- }
-
- void writer_close()
- {
- Lock::Guard guard(_lock);
-
- _writer_is_gone = true;
- _write_ready_sigh = Signal_context_capability();
- _wake_up_reader();
- }
-
- void reader_close()
- {
- Lock::Guard guard(_lock);
- _read_ready_sigh = Signal_context_capability();
- }
-
- bool writer_is_gone() const
- {
- Lock::Guard guard(_lock);
- return _writer_is_gone;
- }
-
- bool any_space_avail_for_writing() const
- {
- Lock::Guard guard(_lock);
- return _any_space_avail_for_writing();
- }
-
- bool data_avail_for_reading() const
- {
- Lock::Guard guard(_lock);
-
- return _read_offset != _write_offset;
- }
-
- size_t read(char *dst, size_t dst_len)
- {
- Lock::Guard guard(_lock);
-
- if (_read_offset < _write_offset) {
-
- size_t len = min(dst_len, _write_offset - _read_offset);
- memcpy(dst, &_buffer[_read_offset], len);
-
- _read_offset += len;
- _wake_up_writer();
-
- return len;
- }
-
- if (_read_offset > _write_offset) {
-
- size_t const upper_len = min(dst_len, BUFFER_SIZE - _read_offset);
- memcpy(dst, &_buffer[_read_offset], upper_len);
-
- size_t const lower_len = min(dst_len - upper_len, _write_offset);
- if (lower_len) {
- memcpy(dst + upper_len, &_buffer[0], lower_len);
- _read_offset = lower_len;
- } else {
- _read_offset += upper_len;
- }
- _wake_up_writer();
-
- return upper_len + lower_len;
- }
-
- /* _read_offset == _write_offset */
- return 0;
- }
-
- /**
- * Write to pipe buffer
- *
- * \return number of written bytes (may be less than 'len')
- */
- size_t write(char *src, size_t len)
- {
- Lock::Guard guard(_lock);
-
- /* trim write request to the available buffer space */
- size_t const trimmed_len = min(len, _avail_buffer_space());
-
- /*
- * Remember pipe state prior writing to see whether a reader
- * must be unblocked after writing.
- */
- bool const pipe_was_empty = (_read_offset == _write_offset);
-
- /* write data up to the upper boundary of the pipe buffer */
- size_t const upper_len = min(BUFFER_SIZE - _write_offset, trimmed_len);
- memcpy(&_buffer[_write_offset], src, upper_len);
-
- _write_offset += upper_len;
-
- /*
- * Determine number of remaining bytes beyond the buffer boundary.
- * The buffer wraps. So this data will end up in the lower part
- * of the pipe buffer.
- */
- size_t const lower_len = trimmed_len - upper_len;
-
- if (lower_len > 0) {
-
- /* pipe buffer wrap-around, write remaining data to the lower part */
- memcpy(&_buffer[0], src + upper_len, lower_len);
- _write_offset = lower_len;
- }
-
- /*
- * Wake up reader who may block for incoming data.
- */
- if (pipe_was_empty || !_any_space_avail_for_writing())
- _wake_up_reader();
-
- /* return number of written bytes */
- return trimmed_len;
- }
-
- void register_write_ready_sigh(Signal_context_capability sigh)
- {
- Lock::Guard guard(_lock);
- _write_ready_sigh = sigh;
- }
-
- void register_read_ready_sigh(Signal_context_capability sigh)
- {
- Lock::Guard guard(_lock);
- _read_ready_sigh = sigh;
- }
-};
-
-
-class Noux::Pipe_sink_io_channel : public Io_channel
-{
- private:
-
- Signal_handler _write_ready_handler;
-
- void _handle_write_ready() { Io_channel::invoke_all_notifiers(); }
-
- Shared_pointer _pipe;
-
- bool _nonblocking { false };
-
- public:
-
- Pipe_sink_io_channel(Shared_pointer pipe, Entrypoint &ep)
- :
- _write_ready_handler(ep, *this, &Pipe_sink_io_channel::_handle_write_ready),
- _pipe(pipe)
- {
- pipe->register_write_ready_sigh(_write_ready_handler);
- }
-
- ~Pipe_sink_io_channel() { _pipe->writer_close(); }
-
- bool check_unblock(bool, bool wr, bool) const override
- {
- return wr && _pipe->any_space_avail_for_writing();
- }
-
- bool nonblocking() override { return _nonblocking; }
-
- bool write(Sysio &sysio) override
- {
- sysio.write_out.count = _pipe->write(sysio.write_in.chunk,
- sysio.write_in.count);
- return true;
- }
-
- bool fcntl(Sysio &sysio) override
- {
- switch (sysio.fcntl_in.cmd) {
-
- case Sysio::FCNTL_CMD_GET_FILE_STATUS_FLAGS:
- sysio.fcntl_out.result = Sysio::OPEN_MODE_WRONLY;
- return true;
-
- case Sysio::FCNTL_CMD_SET_FILE_STATUS_FLAGS:
- _nonblocking = (sysio.fcntl_in.long_arg &
- Sysio::FCNTL_FILE_STATUS_FLAG_NONBLOCK);
- sysio.fcntl_out.result = 0;
- return true;
-
- default:
- return false;
- }
- }
-
- bool fstat(Sysio &sysio) override
- {
- sysio.fstat_out.st.type = Vfs::Node_type::CONTINUOUS_FILE;
- return true;
- }
-};
-
-
-class Noux::Pipe_source_io_channel : public Io_channel
-{
- private:
-
- Signal_handler _read_avail_handler;
-
- void _handle_read_avail() { Io_channel::invoke_all_notifiers(); }
-
- Shared_pointer _pipe;
-
- bool _nonblocking { false };
-
- public:
-
- Pipe_source_io_channel(Shared_pointer pipe, Entrypoint &ep)
- :
- _read_avail_handler(ep, *this, &Pipe_source_io_channel::_handle_read_avail),
- _pipe(pipe)
- {
- _pipe->register_read_ready_sigh(_read_avail_handler);
- }
-
- ~Pipe_source_io_channel() { _pipe->reader_close(); }
-
- bool check_unblock(bool rd, bool, bool) const override
- {
- /* unblock if the writer has already closed its pipe end */
- if (_pipe->writer_is_gone())
- return true;
-
- return (rd && _pipe->data_avail_for_reading());
- }
-
- bool nonblocking() override { return _nonblocking; }
-
- bool read(Sysio &sysio) override
- {
- size_t const max_count =
- min(sysio.read_in.count,
- sizeof(sysio.read_out.chunk));
-
- sysio.read_out.count =
- _pipe->read(sysio.read_out.chunk, max_count);
-
- return true;
- }
-
- bool fcntl(Sysio &sysio) override
- {
- switch (sysio.fcntl_in.cmd) {
-
- case Sysio::FCNTL_CMD_GET_FILE_STATUS_FLAGS:
- sysio.fcntl_out.result = Sysio::OPEN_MODE_RDONLY;
- return true;
-
- case Sysio::FCNTL_CMD_SET_FILE_STATUS_FLAGS:
- _nonblocking = (sysio.fcntl_in.long_arg &
- Sysio::FCNTL_FILE_STATUS_FLAG_NONBLOCK);
- sysio.fcntl_out.result = 0;
- return true;
-
- default:
- return false;
- }
- }
-
- bool fstat(Sysio &sysio) override
- {
- sysio.fstat_out.st.type = Vfs::Node_type::CONTINUOUS_FILE;
- return true;
- }
-};
-
-#endif /* _NOUX__PIPE_IO_CHANNEL_H_ */
diff --git a/repos/ports/src/noux/range_checked_index.h b/repos/ports/src/noux/range_checked_index.h
deleted file mode 100644
index c3de0fdc15..0000000000
--- a/repos/ports/src/noux/range_checked_index.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * \brief Utility for checking array bounds
- * \author Norman Feske
- * \date 2011-02-18
- */
-
-/*
- * Copyright (C) 2011-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__RANGE_CHECKED_INDEX_H_
-#define _NOUX__RANGE_CHECKED_INDEX_H_
-
-namespace Noux {
-
- class Index_out_of_range { };
- template struct Range_checked_index;
-}
-
-
-template
-struct Noux::Range_checked_index
-{
- T value;
- T const max;
-
- Range_checked_index(T value, T max) : value(value), max(max) { }
-
- Range_checked_index operator++ (int)
- {
- T old_value = value;
-
- if (++value >= max)
- throw Index_out_of_range();
-
- return Range_checked_index(old_value, max);
- }
-
- operator T () { return value; }
-};
-
-#endif /* _NOUX__RANGE_CHECKED_INDEX_H_ */
diff --git a/repos/ports/src/noux/region_map_component.h b/repos/ports/src/noux/region_map_component.h
deleted file mode 100644
index 89a94535f4..0000000000
--- a/repos/ports/src/noux/region_map_component.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * \brief Region map implementation used by Noux processes
- * \author Norman Feske
- * \author Martin Stein
- * \date 2012-02-22
- *
- * The custom region-map implementation is used for recording all regions
- * attached to the region map. Using the recorded information, the address-
- * space layout can then be replayed onto a new process created via fork.
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NOUX__REGION_MAP_COMPONENT_H_
-#define _NOUX__REGION_MAP_COMPONENT_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-
-/* Noux includes */
-#include