diff --git a/ports/src/noux/child.h b/ports/src/noux/child.h index 45c8092f9..5fc6a6445 100644 --- a/ports/src/noux/child.h +++ b/ports/src/noux/child.h @@ -60,7 +60,6 @@ namespace Noux { } }; - /** * Return singleton instance of PID allocator */ @@ -168,12 +167,28 @@ namespace Noux { */ Environment _env; - Dir_file_system * const _root_dir; - /** - * ELF binary + * ELF binary handling */ - Dataspace_capability const _binary_ds; + struct Elf + { + enum { NAME_MAX_LEN = 128 }; + char _name[NAME_MAX_LEN]; + + Dir_file_system * const _root_dir; + Dataspace_capability const _binary_ds; + + Elf(char const * const binary_name, Dir_file_system * root_dir, + Dataspace_capability binary_ds) + : + _root_dir(root_dir), _binary_ds(binary_ds) + { + strncpy(_name, binary_name, sizeof(_name)); + _name[NAME_MAX_LEN - 1] = 0; + } + + ~Elf() { _root_dir->release(_name, _binary_ds); } + } _elf; enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) }; enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) }; @@ -235,6 +250,8 @@ namespace Noux { io->unregister_wake_up_notifier(¬ifier); } + Dir_file_system * const root_dir() { return _elf._root_dir; } + /** * Method for handling noux network related system calls */ @@ -258,7 +275,7 @@ namespace Noux { * looked up at the virtual file * system */ - Child(char const *name, + Child(char const *binary_name, Family_member *parent, int pid, Signal_receiver *sig_rec, @@ -281,11 +298,10 @@ namespace Noux { _destruct_context_cap(sig_rec->manage(&_destruct_dispatcher)), _cap_session(cap_session), _entrypoint(cap_session, STACK_SIZE, "noux_process", false), - _resources(name, resources_ep, false), + _resources(binary_name, resources_ep, false), _args(ARGS_DS_SIZE, args), _env(env), - _root_dir(root_dir), - _binary_ds(root_dir->dataspace(name)), + _elf(binary_name, root_dir, root_dir->dataspace(binary_name)), _sysio_ds(Genode::env()->ram_session(), SYSIO_DS_SIZE), _sysio(_sysio_ds.local_addr()), _noux_session_cap(Session_capability(_entrypoint.manage(this))), @@ -295,18 +311,18 @@ namespace Noux { _local_rm_service(_entrypoint, _resources.ds_registry), _local_rom_service(_entrypoint, _resources.ds_registry), _parent_services(parent_services), - _binary_ds_info(_resources.ds_registry, _binary_ds), + _binary_ds_info(_resources.ds_registry, _elf._binary_ds), _sysio_ds_info(_resources.ds_registry, _sysio_ds.cap()), _ldso_ds_info(_resources.ds_registry, ldso_ds_cap()), _args_ds_info(_resources.ds_registry, _args.cap()), _env_ds_info(_resources.ds_registry, _env.cap()), - _child_policy(name, _binary_ds, _args.cap(), _env.cap(), + _child_policy(_elf._name, _elf._binary_ds, _args.cap(), _env.cap(), _entrypoint, _local_noux_service, _local_rm_service, _local_rom_service, _parent_services, *this, *this, _destruct_context_cap, _resources.ram, verbose), - _child(forked ? Dataspace_capability() : _binary_ds, + _child(forked ? Dataspace_capability() : _elf._binary_ds, _resources.ram.cap(), _resources.cpu.cap(), _resources.rm.cap(), &_entrypoint, &_child_policy, /** @@ -317,8 +333,8 @@ namespace Noux { if (verbose) _args.dump(); - if (!forked && !_binary_ds.valid()) { - PERR("Lookup of executable \"%s\" failed", name); + if (!forked && !_elf._binary_ds.valid()) { + PERR("Lookup of executable \"%s\" failed", binary_name); throw Binary_does_not_exist(); } } @@ -328,8 +344,6 @@ namespace Noux { _sig_rec->dissolve(&_destruct_dispatcher); _entrypoint.dissolve(this); - - _root_dir->release(_child_policy.name(), _binary_ds); } void start() { _entrypoint.activate(); } diff --git a/ports/src/noux/child_policy.h b/ports/src/noux/child_policy.h index 481069b10..17d17dbea 100644 --- a/ports/src/noux/child_policy.h +++ b/ports/src/noux/child_policy.h @@ -30,8 +30,6 @@ namespace Noux { { private: - enum { NAME_MAX_LEN = 128 }; - char _name_buf[NAME_MAX_LEN]; char const *_name; Init::Child_policy_enforce_labeling _labeling_policy; Init::Child_policy_provide_rom_file _binary_policy; @@ -64,7 +62,7 @@ namespace Noux { Ram_session &ref_ram_session, bool verbose) : - _name(strncpy(_name_buf, name, sizeof(_name_buf))), + _name(name), _labeling_policy(_name), _binary_policy("binary", binary_ds, &entrypoint), _args_policy( "args", args_ds, &entrypoint), diff --git a/ports/src/noux/main.cc b/ports/src/noux/main.cc index 30b163ddb..a6a9f1670 100644 --- a/ports/src/noux/main.cc +++ b/ports/src/noux/main.cc @@ -175,7 +175,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_STAT: case SYSCALL_LSTAT: /* XXX implement difference between 'lstat' and 'stat' */ { - bool result = _root_dir->stat(_sysio, _sysio->stat_in.path); + bool result = root_dir()->stat(_sysio, _sysio->stat_in.path); /** * Instead of using the uid/gid given by the actual file system @@ -207,11 +207,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_OPEN: { - Vfs_handle *vfs_handle = _root_dir->open(_sysio, _sysio->open_in.path); + Vfs_handle *vfs_handle = root_dir()->open(_sysio, _sysio->open_in.path); if (!vfs_handle) return false; - char const *leaf_path = _root_dir->leaf_path(_sysio->open_in.path); + char const *leaf_path = root_dir()->leaf_path(_sysio->open_in.path); /* * File descriptors of opened directories are handled by @@ -219,12 +219,12 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * path because path operations always refer to the global * root. */ - if (vfs_handle->ds() == _root_dir) + if (vfs_handle->ds() == root_dir()) leaf_path = _sysio->open_in.path; Shared_pointer channel(new Vfs_io_channel(_sysio->open_in.path, - leaf_path, _root_dir, vfs_handle), + leaf_path, root_dir(), vfs_handle), Genode::env()->heap()); _sysio->open_out.fd = add_io_channel(channel); @@ -257,7 +257,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * does not exist. */ Dataspace_capability binary_ds = - _root_dir->dataspace(_sysio->execve_in.filename); + root_dir()->dataspace(_sysio->execve_in.filename); if (!binary_ds.valid()) { _sysio->error.execve = Sysio::EXECVE_NONEXISTENT; @@ -268,23 +268,23 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) child_env(_sysio->execve_in.filename, binary_ds, _sysio->execve_in.args, _sysio->execve_in.env); - _root_dir->release(_sysio->execve_in.filename, binary_ds); + root_dir()->release(_sysio->execve_in.filename, binary_ds); - binary_ds = _root_dir->dataspace(child_env.binary_name()); + binary_ds = root_dir()->dataspace(child_env.binary_name()); if (!binary_ds.valid()) { _sysio->error.execve = Sysio::EXECVE_NONEXISTENT; return false; } - _root_dir->release(child_env.binary_name(), binary_ds); + root_dir()->release(child_env.binary_name(), binary_ds); try { Child *child = new Child(child_env.binary_name(), parent(), pid(), _sig_rec, - _root_dir, + root_dir(), child_env.args(), child_env.env(), _cap_session, @@ -501,7 +501,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) this, new_pid, _sig_rec, - _root_dir, + root_dir(), _args, _env.env(), _cap_session, @@ -584,25 +584,25 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_UNLINK: - return _root_dir->unlink(_sysio, _sysio->unlink_in.path); + return root_dir()->unlink(_sysio, _sysio->unlink_in.path); case SYSCALL_READLINK: - return _root_dir->readlink(_sysio, _sysio->readlink_in.path); + return root_dir()->readlink(_sysio, _sysio->readlink_in.path); case SYSCALL_RENAME: - return _root_dir->rename(_sysio, _sysio->rename_in.from_path, + return root_dir()->rename(_sysio, _sysio->rename_in.from_path, _sysio->rename_in.to_path); case SYSCALL_MKDIR: - return _root_dir->mkdir(_sysio, _sysio->mkdir_in.path); + return root_dir()->mkdir(_sysio, _sysio->mkdir_in.path); case SYSCALL_SYMLINK: - return _root_dir->symlink(_sysio, _sysio->symlink_in.newpath); + return root_dir()->symlink(_sysio, _sysio->symlink_in.newpath); case SYSCALL_USERINFO: {