diff --git a/repos/libports/run/execve.run b/repos/libports/run/execve.run
index 424c32dabb..c20fcd75c4 100644
--- a/repos/libports/run/execve.run
+++ b/repos/libports/run/execve.run
@@ -16,9 +16,13 @@ install_config {
-
+
-
+
+
+
+
+
}
diff --git a/repos/libports/src/lib/libc/execve.cc b/repos/libports/src/lib/libc/execve.cc
index ee9000e4a8..5a89d61414 100644
--- a/repos/libports/src/lib/libc/execve.cc
+++ b/repos/libports/src/lib/libc/execve.cc
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
using namespace Genode;
@@ -161,6 +162,13 @@ extern "C" int execve(char const *filename,
return Libc::Errno(EACCES);
}
+ Libc::Absolute_path resolved_path;
+ try {
+ Libc::resolve_symlinks(filename, resolved_path); }
+ catch (Libc::Symlink_resolve_error) {
+ warning("execve: ", filename, " does not exist");
+ return Libc::Errno(ENOENT); }
+
/* capture environment variables and args to libc-internal heap */
Libc::String_array *saved_env_vars =
new (*_alloc_ptr) Libc::String_array(*_alloc_ptr, envp);
@@ -169,7 +177,7 @@ extern "C" int execve(char const *filename,
new (*_alloc_ptr) Libc::String_array(*_alloc_ptr, argv);
try {
- _main_ptr = Dynamic_linker::respawn(*_env_ptr, filename, "main");
+ _main_ptr = Dynamic_linker::respawn(*_env_ptr, resolved_path.string(), "main");
}
catch (Dynamic_linker::Invalid_symbol) {
error("Dynamic_linker::respawn could not obtain binary entry point");
diff --git a/repos/libports/src/lib/libc/fork.cc b/repos/libports/src/lib/libc/fork.cc
index 8f81f8a17c..1b9807b562 100644
--- a/repos/libports/src/lib/libc/fork.cc
+++ b/repos/libports/src/lib/libc/fork.cc
@@ -478,12 +478,21 @@ struct Libc::Forked_child : Child_policy, Child_ready
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
{
+ Session_label rewritten_label = label;
+
Service *service_ptr = nullptr;
if (_state == State::STARTING_UP && name == Clone_session::service_name())
service_ptr = &_local_clone_service.service;
if (name == Rom_session::service_name()) {
+ /*
+ * Strip off the originating child name to allow the application of
+ * routing rules based on the leading path elements, regardless
+ * of which child in the process hierarchy requests a ROM.
+ */
+ rewritten_label = label.last_element();
+
try { service_ptr = &_local_rom_services.matching_service(name, label); }
catch (...) { }
@@ -496,7 +505,7 @@ struct Libc::Forked_child : Child_policy, Child_ready
if (service_ptr)
return Route { .service = *service_ptr,
- .label = label,
+ .label = rewritten_label,
.diag = Session::Diag() };
throw Service_denied();
diff --git a/repos/libports/src/lib/libc/internal/file_operations.h b/repos/libports/src/lib/libc/internal/file_operations.h
new file mode 100644
index 0000000000..1d9366e795
--- /dev/null
+++ b/repos/libports/src/lib/libc/internal/file_operations.h
@@ -0,0 +1,35 @@
+/*
+ * \brief Libc-internal file operations
+ * \author Norman Feske
+ * \date 2019-09-23
+ */
+
+/*
+ * Copyright (C) 2019 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 _LIBC__INTERNAL__FILE_OPERATIONS_H_
+#define _LIBC__INTERNAL__FILE_OPERATIONS_H_
+
+/* Genode includes */
+#include
+
+/* libc includes */
+#include /* for 'PATH_MAX' */
+
+/* libc-internal includes */
+#include
+
+namespace Libc {
+
+ typedef Genode::Path Absolute_path;
+
+ class Symlink_resolve_error : Exception { };
+
+ void resolve_symlinks(char const *path, Absolute_path &resolved_path);
+}
+
+#endif /* _LIBC__INTERNAL__FILE_OPERATIONS_H_ */
diff --git a/repos/ports/run/bash.run b/repos/ports/run/bash.run
index 6fcf0f55ab..f88a61a99e 100644
--- a/repos/ports/run/bash.run
+++ b/repos/ports/run/bash.run
@@ -87,7 +87,7 @@ install_config {
-
+
@@ -103,7 +103,7 @@ install_config {
-
+
-
-
+
+