diff --git a/repos/libports/run/fork.run b/repos/libports/run/fork.run
new file mode 100644
index 0000000000..03dc7c27fe
--- /dev/null
+++ b/repos/libports/run/fork.run
@@ -0,0 +1,37 @@
+build { core init test/fork }
+
+create_boot_directory
+
+install_config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0123456789
+
+
+
+
+
+}
+
+build_boot_image {
+ core init ld.lib.so libc.lib.so vfs.lib.so libm.lib.so posix.lib.so test-fork
+}
+
+append qemu_args " -nographic "
+
+run_genode_until "--- parent done ---.*\n" 20
+run_genode_until "child.*exited.*\n" 5 [output_spawn_id]
diff --git a/repos/ports/src/test/noux_fork/target.mk b/repos/libports/src/test/fork/target.mk
similarity index 69%
rename from repos/ports/src/test/noux_fork/target.mk
rename to repos/libports/src/test/fork/target.mk
index 9d94b98418..cb2bda101a 100644
--- a/repos/ports/src/test/noux_fork/target.mk
+++ b/repos/libports/src/test/fork/target.mk
@@ -1,4 +1,4 @@
-TARGET = test-noux_fork
+TARGET = test-fork
SRC_CC = test.cc
LIBS = posix
diff --git a/repos/libports/src/test/fork/test.cc b/repos/libports/src/test/fork/test.cc
new file mode 100644
index 0000000000..6f4ec4f282
--- /dev/null
+++ b/repos/libports/src/test/fork/test.cc
@@ -0,0 +1,121 @@
+/*
+ * \brief Simple fork test
+ * \author Norman Feske
+ * \date 2012-02-14
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+enum { MAX_COUNT = 100 };
+
+int main(int, char **argv)
+{
+ printf("--- test-fork started ---\n");
+
+ enum { MSG_SIZE = 100 };
+ static char message_in_rw_segment[MSG_SIZE];
+ char const * const message_about_rw_segment = "message stored in rw segment";
+ strncpy(message_in_rw_segment, message_about_rw_segment, MSG_SIZE);
+
+ char * const message_on_heap = (char *)malloc(MSG_SIZE);
+ char const * const message_about_heap = "message stored on the heap";
+ strncpy(message_on_heap, message_about_heap, MSG_SIZE - 1);
+
+ enum { ARGV0_SIZE = 100 };
+ static char parent_argv0[ARGV0_SIZE];
+ strncpy(parent_argv0, argv[0], ARGV0_SIZE - 1);
+
+ pid_t fork_ret = fork();
+ if (fork_ret < 0) {
+ printf("Error: fork returned %d, errno=%d\n", fork_ret, errno);
+ return -1;
+ }
+
+ printf("pid %d: fork returned %d\n", getpid(), fork_ret);
+
+ /* child */
+ if (fork_ret == 0) {
+ printf("pid %d: child says hello\n", getpid());
+
+ /*
+ * Validate that the child's heap and RW segment correspond to the
+ * the state of the parent.
+ */
+ printf("RW segment: %s\n", message_in_rw_segment);
+ if (strcmp(message_in_rw_segment, message_about_rw_segment)) {
+ printf("Error: unexpected content of the child's RW segment\n");
+ return -1;
+ }
+
+ printf("argv0: %s\n", argv[0]);
+ if (!argv[0] || strcmp(argv[0], parent_argv0)) {
+ printf("Error: unexpected content of the child's args buffer\n");
+ return -1;
+ }
+
+ printf("heap: %s\n", message_on_heap);
+ if (strcmp(message_on_heap, message_about_heap)) {
+ printf("Error: unexpected content on the child's heap\n");
+ return -1;
+ }
+
+ {
+ char c = 0;
+ if (read(3, &c, 1) == 1) {
+ printf("read character '%c' from FD 3\n", c);
+ if (c != '5') {
+ printf("Error: read unexpected value from FD 3\n");
+ return -1;
+ }
+ }
+ }
+
+ pid_t fork_ret = fork();
+ if (fork_ret < 0) {
+ printf("Error: fork returned %d, errno=%d\n", fork_ret, errno);
+ return -1;
+ }
+
+ printf("pid %d: fork returned %d\n", getpid(), fork_ret);
+
+ /* grand child */
+ if (fork_ret == 0) {
+ printf("pid %d: grand child says hello\n", getpid());
+
+ for (int k = 0; k < MAX_COUNT; k++) {
+ printf("pid %d: grand child k = %d\n", getpid(), k);
+ }
+
+ return 0;
+ };
+
+ for (int j = 0; j < MAX_COUNT; j++) {
+ printf("pid %d: child j = %d\n", getpid(), j);
+ }
+
+ if (fork_ret != 0) {
+ printf("pid %d: child waits for grand-child exit\n", getpid());
+ waitpid(fork_ret, nullptr, 0);
+ }
+
+ return 0;
+ }
+
+ printf("pid %d: parent received child pid %d, starts counting...\n",
+ getpid(), fork_ret);
+
+ for (int i = 0; i < MAX_COUNT; ) {
+ printf("pid %d: parent i = %d\n", getpid(), i++);
+ }
+
+ printf("pid %d: parent waits for child exit\n", getpid());
+ waitpid(fork_ret, nullptr, 0);
+
+ printf("--- parent done ---\n");
+ return 0;
+}
diff --git a/repos/ports/run/noux_fork.run b/repos/ports/run/noux_fork.run
index 39e8467435..1c0f50e75d 100644
--- a/repos/ports/run/noux_fork.run
+++ b/repos/ports/run/noux_fork.run
@@ -1,6 +1,6 @@
build {
core init timer server/log_terminal noux lib/libc_noux
- test/noux_fork
+ test/fork
}
create_boot_directory
@@ -34,9 +34,9 @@ install_config {
-
+
-
+
@@ -44,7 +44,7 @@ install_config {
build_boot_image {
core init timer log_terminal noux ld.lib.so libc.lib.so vfs.lib.so libm.lib.so
- libc_noux.lib.so posix.lib.so test-noux_fork
+ libc_noux.lib.so posix.lib.so test-fork
}
append qemu_args " -nographic "
diff --git a/repos/ports/src/test/noux_fork/test.cc b/repos/ports/src/test/noux_fork/test.cc
deleted file mode 100644
index 5d35f07038..0000000000
--- a/repos/ports/src/test/noux_fork/test.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * \brief Simple fork test
- * \author Norman Feske
- * \date 2012-02-14
- */
-
-#include
-#include
-#include
-#include
-
-enum { MAX_COUNT = 1000 };
-
-int main(int, char **)
-{
- printf("--- test-noux_fork started ---\n");
-
- pid_t fork_ret = fork();
- if (fork_ret < 0) {
- printf("Error: fork returned %d, errno=%d\n", fork_ret, errno);
- return -1;
- }
-
- printf("pid %d: fork returned %d\n", getpid(), fork_ret);
-
- /* child */
- if (fork_ret == 0) {
- printf("pid %d: child says hello\n", getpid());
-
- pid_t fork_ret = fork();
- if (fork_ret < 0) {
- printf("Error: fork returned %d, errno=%d\n", fork_ret, errno);
- return -1;
- }
-
- printf("pid %d: fork returned %d\n", getpid(), fork_ret);
-
- /* grand child */
- if (fork_ret == 0) {
- printf("pid %d: grand child says hello\n", getpid());
-
- for (int k = 0; k < MAX_COUNT; k++) {
- printf("pid %d: grand child k = %d\n", getpid(), k);
- }
-
- return 0;
- };
-
- for (int j = 0; j < MAX_COUNT; j++) {
- printf("pid %d: child j = %d\n", getpid(), j);
- }
-
- if (fork_ret != 0) {
- printf("pid %d: child waits for grand-child exit\n", getpid());
- waitpid(fork_ret, nullptr, 0);
- }
-
- return 0;
- }
-
- printf("pid %d: parent received child pid %d, starts counting...\n",
- getpid(), fork_ret);
-
- for (int i = 0; i < MAX_COUNT; ) {
- printf("pid %d: parent i = %d\n", getpid(), i++);
- }
-
- printf("pid %d: parent waits for child exit\n", getpid());
- waitpid(fork_ret, nullptr, 0);
-
- printf("--- parent done ---\n");
- return 0;
-}