/* * \brief Test for thread-local errno handling of hybrid Linux/Genode programs * \author Norman Feske * \date 2011-12-05 */ /* Genode includes */ #include #include #include /* libc includes */ #include #include #include #include enum { STACK_SIZE = 4096 }; struct Thread : Genode::Thread_deprecated { Genode::Blockade &_barrier; Thread(Genode::Blockade &barrier) : Genode::Thread_deprecated("stat"), _barrier(barrier) { start(); } void entry() override { /* * Stat syscall should return with errno ENOENT */ struct stat buf; int ret = stat("", &buf); Genode::log("thread: stat returned ", ret, ", errno=", errno); /* * Let main thread procees */ _barrier.wakeup(); } }; static int exit_status; static void exit_on_suspended() { exit(exit_status); } struct Unexpected_errno_change { }; /* * Component implements classical main function in construct. */ void Component::construct(Genode::Env &env) { Genode::log("--- thread-local errno test ---"); static Genode::Blockade barrier; int const orig_errno = errno; Genode::log("main: before thread creation, errno=", orig_errno); /* create thread, which modifies its thread-local errno value */ static Thread thread(barrier); /* block until the thread performed a 'stat' syscall */ barrier.block(); Genode::log("main: after thread completed, errno=", errno); if (orig_errno != errno) { Genode::error("unexpected change of main thread's errno value"); throw Unexpected_errno_change(); } Genode::log("--- finished thread-local errno test ---"); exit_status = 0; env.ep().schedule_suspend(exit_on_suspended, nullptr); }