diff --git a/base-linux/src/platform/lx_hybrid.cc b/base-linux/src/platform/lx_hybrid.cc index eb0925f46a..caf3d6c268 100644 --- a/base-linux/src/platform/lx_hybrid.cc +++ b/base-linux/src/platform/lx_hybrid.cc @@ -48,6 +48,16 @@ __attribute__((constructor(101))) void lx_hybrid_init() lx_environ = environ; } +/* + * Dummy symbols to let generic tests programs (i.e., 'test-config_args') link + * successfully. Please note that such programs are not expected to work when + * built as hybrid Linux/Genode programs because when using the glibc startup + * code, we cannot manipulate argv prior executing main. However, by defining + * these symbols, we prevent the automated build bot from stumbling over such + * binaries. + */ +char **genode_argv = 0; +int genode_argc = 1; /************ ** Thread ** diff --git a/os/lib/mk/config_args.mk b/os/lib/mk/config_args.mk new file mode 100644 index 0000000000..dbf9be6a1e --- /dev/null +++ b/os/lib/mk/config_args.mk @@ -0,0 +1,3 @@ +SRC_CC = config_args.cc + +vpath %.cc $(REP_DIR)/src/lib/config_args diff --git a/os/run/config_args.run b/os/run/config_args.run new file mode 100644 index 0000000000..f6f5eee8ea --- /dev/null +++ b/os/run/config_args.run @@ -0,0 +1,42 @@ +build "core init drivers/timer test/config_args" + +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +build_boot_image "core init timer test-config_args" + +append qemu_args "-nographic -m 64" + +run_genode_until {--- end of config args test ---} 10 + +puts "Test succeeded" diff --git a/os/src/lib/config_args/config_args.cc b/os/src/lib/config_args/config_args.cc new file mode 100644 index 0000000000..73ab5b7ab4 --- /dev/null +++ b/os/src/lib/config_args/config_args.cc @@ -0,0 +1,68 @@ +/* + * \brief Read program arguments from the config file + * \date 2012-04-19 + * \author Christian Prochaska + */ + +/* + * Copyright (C) 2012 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. + */ + +#include + +using namespace Genode; + + +/* external symbols provided by Genode's startup code */ +extern char **genode_argv; +extern int genode_argc; + + +__attribute__((constructor)) +void init_config_args(void) +{ + int argc = 0; + static char **argv; + + /* count the number of arguments */ + try { + Xml_node arg_node = config()->xml_node().sub_node("arg"); + for (;;) { + /* check if the 'value' attribute exists */ + arg_node.attribute("value"); + argc++; + arg_node = arg_node.next("arg"); + } + } + catch (Config::Invalid) { return; } + catch (Xml_node::Nonexistent_sub_node) { } + catch (Xml_node::Nonexistent_attribute) + { + PERR(" node has no 'value' attribute, ignoring further nodes"); + } + + if (argc == 0) + return; + + argv = (char**)env()->heap()->alloc(argc * sizeof(char*)); + + /* read the arguments */ + Xml_node arg_node = config()->xml_node().sub_node("arg"); + try { + for (int i = 0; i < argc; i++) { + static char buf[512]; + arg_node.attribute("value").value(buf, sizeof(buf)); + size_t arg_size = strlen(buf) + 1; + argv[i] = (char*)env()->heap()->alloc(arg_size); + strncpy(argv[i], buf, arg_size); + arg_node = arg_node.next("arg"); + } + } catch (Xml_node::Nonexistent_sub_node) { } + + /* register command-line arguments at Genode's startup code */ + genode_argc = argc; + genode_argv = argv; +} diff --git a/os/src/test/config_args/main.cc b/os/src/test/config_args/main.cc new file mode 100644 index 0000000000..e1383363af --- /dev/null +++ b/os/src/test/config_args/main.cc @@ -0,0 +1,42 @@ +/* + * \brief 'main()' arguments test + * \author Christian Prochaska + * \date 2012-04-19 + * + */ + +/* + * Copyright (C) 2012 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. + */ + +#include +#include + +using namespace Genode; + +int main(int argc, char **argv) +{ + printf("--- config args test started ---\n"); + + if (argc != 2) { + PERR("Error: argc is not as expected"); + return -1; + } + + if (strcmp(argv[0], "test-config_args") != 0) { + PERR("Error: argv[0] is not as expected"); + return -1; + } + + if (strcmp(argv[1], "-testarg") != 0) { + PERR("Error: argv[1] is not as expected"); + return -1; + } + + printf("--- end of config args test ---\n"); + + return 0; +} diff --git a/os/src/test/config_args/target.mk b/os/src/test/config_args/target.mk new file mode 100644 index 0000000000..08c6b4ccbd --- /dev/null +++ b/os/src/test/config_args/target.mk @@ -0,0 +1,3 @@ +TARGET = test-config_args +LIBS = env config_args +SRC_CC = main.cc