diff --git a/repos/libports/run/libc_component.run b/repos/libports/run/libc_component.run new file mode 100644 index 0000000000..c68aa42752 --- /dev/null +++ b/repos/libports/run/libc_component.run @@ -0,0 +1,103 @@ +# +# Build +# + +set build_components { + core init drivers/timer server/terminal_crosslink + test/libc_counter test/libc_component +} + +build $build_components + +create_boot_directory + +# +# Generate config +# + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# + + +set boot_modules { + core init timer terminal_crosslink + test-libc_counter-source test-libc_component + ld.lib.so libc.lib.so libm.lib.so +} + +build_boot_image $boot_modules + +append qemu_args "-nographic -m 128" + +# +# Execute test case +# + +run_genode_until forever +run_genode_until "child \"test-libc_counter-sink\" exited with exit value 0.*\n" 30 + +# vi: set ft=tcl : diff --git a/repos/libports/run/libc_vfs_component.run b/repos/libports/run/libc_vfs_component.run new file mode 100644 index 0000000000..c8c06bd31a --- /dev/null +++ b/repos/libports/run/libc_vfs_component.run @@ -0,0 +1,114 @@ +# +# Build +# + +set build_components { + core init drivers/timer server/terminal_crosslink server/vfs + test/libc_counter test/libc_component +} + +build $build_components + +create_boot_directory + +# +# Generate config +# + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# + + +set boot_modules { + core init timer terminal_crosslink vfs + test-libc_counter-source test-libc_component + ld.lib.so libc.lib.so libm.lib.so +} + +build_boot_image $boot_modules + +append qemu_args "-nographic -m 128" + +# +# Execute test case +# + +run_genode_until forever +run_genode_until "child \"test-libc_counter-sink\" exited with exit value 0.*\n" 30 + +# vi: set ft=tcl : diff --git a/repos/libports/src/lib/libc/task.cc b/repos/libports/src/lib/libc/task.cc index 763b368ccf..217d12fe16 100644 --- a/repos/libports/src/lib/libc/task.cc +++ b/repos/libports/src/lib/libc/task.cc @@ -510,8 +510,9 @@ struct Libc::Kernel return; } - _app_returned = false; - _app_code = &app_code; + _resume_main_once = false; + _app_returned = false; + _app_code = &app_code; /* save continuation of libc kernel (incl. current stack) */ if (!_setjmp(_kernel_context)) { @@ -526,7 +527,7 @@ struct Libc::Kernel while (!_app_returned) { _env.ep().wait_and_dispatch_one_signal(); - if (_resume_main_once) + if (_resume_main_once && !_setjmp(_kernel_context)) _switch_to_user(); } } @@ -665,8 +666,6 @@ void Libc::schedule_suspend(void (*suspended) ()) void Libc::execute_in_application_context(Libc::Application_code &app_code) { - warning("executing code in application context, not implemented"); - /* * XXX We don't support a second entrypoint - pthreads should work as they * don't use this code. @@ -687,8 +686,6 @@ void Libc::execute_in_application_context(Libc::Application_code &app_code) nested = true; kernel->run(app_code); nested = false; - - warning("leaving application context"); } diff --git a/repos/libports/src/test/libc_component/main.cc b/repos/libports/src/test/libc_component/main.cc new file mode 100644 index 0000000000..6f8d01309c --- /dev/null +++ b/repos/libports/src/test/libc_component/main.cc @@ -0,0 +1,175 @@ +/* + * \brief Libc-component using select test + * \author Christian Helmuth + * \date 2017-02-09 + */ + +/* + * Copyright (C) 2017 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. + */ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include + +/* libc includes */ +#include +#include +#include +#include +#include +#include +#include + + +namespace Log { + using Genode::Static_root; + using Genode::Log_session; + + struct Session_component; + struct Main; +} + + +static void die(char const *token) __attribute__((noreturn)); +static void die(char const *token) +{ + Genode::error("[", Genode::Cstring(token), "] ", Genode::Cstring(strerror(errno))); + exit(1); +} + + +static void use_file_system() +{ + int result = 0; + + int const fd = open("/tmp/blub", O_RDWR | O_NONBLOCK | O_CREAT | O_APPEND); + if (fd == -1) die("open"); + + printf("open returned fd %d\n", fd); + + static char buf[1024]; + + result = read(fd, buf, sizeof(buf)); + if (result == -1) die("read"); + + printf("read %d bytes\n", result); + + result = write(fd, "X", 1); + if (result == -1) die("write"); + + printf("wrote %d bytes\n", result); + + result = close(fd); + if (result == -1) die("close"); +} + + +struct Log::Session_component : Genode::Rpc_object +{ + char _buf[Log_session::MAX_STRING_LEN]; + int _fd = -1; + fd_set _readfds; + fd_set _writefds; + fd_set _exceptfds; + + void _select() + { + int nready = 0; + do { + fd_set readfds = _readfds; + fd_set writefds = _writefds; + fd_set exceptfds = _exceptfds; + + nready = _select_handler.select(_fd + 1, readfds, writefds, exceptfds); + if (nready) + _select_ready(nready, readfds, writefds, exceptfds); + } while (nready); + } + + Libc::Select_handler _select_handler { + *this, &Session_component::_select_ready }; + + void _select_ready(int nready, fd_set const &readfds, fd_set const &writefds, fd_set const &exceptfds) + { + Libc::with_libc([&] () { + if (nready <= 0) { + Genode::warning("select handler reported nready=", nready); + return; + } + if (!FD_ISSET(_fd, &readfds)) { + Genode::warning("select handler reported unexpected fd, nready=", nready); + + for (unsigned i = 0; i < FD_SETSIZE; ++i) + if (FD_ISSET(i, &readfds)) Genode::log("fd ", i, " readable"); + for (unsigned i = 0; i < FD_SETSIZE; ++i) + if (FD_ISSET(i, &writefds)) Genode::log("fd ", i, " writeable"); + for (unsigned i = 0; i < FD_SETSIZE; ++i) + if (FD_ISSET(i, &exceptfds)) Genode::log("fd ", i, " exceptable?"); + + return; + } + int const result = read(_fd, _buf, sizeof(_buf)-1); + if (result <= 0) { + Genode::warning("read returned ", result, " in select handler"); + return; + } + _buf[result] = 0; + Genode::log("read from file \"", Genode::Cstring(_buf), "\""); + }); + } + + Session_component() + { + Libc::with_libc([&] () { + _fd = open("/dev/terminal", O_RDWR); + if (_fd == -1) die("open"); + + FD_ZERO(&_readfds); + FD_ZERO(&_writefds); + FD_ZERO(&_exceptfds); + FD_SET(_fd, &_readfds); + }); + } + + Genode::size_t write(String const &string_buf) + { + if (!(string_buf.valid_string())) { return 0; } + + strncpy(_buf, string_buf.string(), sizeof(_buf)); + size_t len = strlen(_buf); + + if (_buf[len-1] == '\n') _buf[len-1] = 0; + + Genode::log("RPC with \"", Genode::Cstring(_buf), "\""); + + _select(); + + return len; + } +}; + + +struct Log::Main +{ + Libc::Env &_env; + Session_component _session { }; + Static_root _root { _env.ep().manage(_session) }; + + Main(Libc::Env &env) : _env(env) + { + Libc::with_libc([] () { use_file_system(); }); + + _env.parent().announce(_env.ep().manage(_root)); + } +}; + + +void Libc::Component::construct(Libc::Env &env) { static Log::Main inst(env); } diff --git a/repos/libports/src/test/libc_component/target.mk b/repos/libports/src/test/libc_component/target.mk new file mode 100644 index 0000000000..2dd1983165 --- /dev/null +++ b/repos/libports/src/test/libc_component/target.mk @@ -0,0 +1,3 @@ +TARGET = test-libc_component +SRC_CC = main.cc +LIBS = libc