diff --git a/repos/libports/run/fork.run b/repos/libports/run/fork.run new file mode 100644 index 000000000..03dc7c27f --- /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 9d94b9841..cb2bda101 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 000000000..6f4ec4f28 --- /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 39e846743..1c0f50e75 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 5d35f0703..000000000 --- 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; -}