mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
libc: tests for components using RPC and select()
This commit is contained in:
parent
0aac473229
commit
f7f18710de
103
repos/libports/run/libc_component.run
Normal file
103
repos/libports/run/libc_component.run
Normal file
@ -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 {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="terminal_crosslink">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Terminal"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="test-libc_component">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="LOG"/> </provides>
|
||||
<config ld_verbose="yes">
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <terminal/> </dir>
|
||||
<dir name="tmp"> <ram/> </dir>
|
||||
</vfs>
|
||||
<libc stdin="/dev/log" stdout="/dev/log" stderr="/dev/log"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="counter-terminal">
|
||||
<binary name="test-libc_counter-source"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="dev"> <terminal/> <log/> </dir>
|
||||
</vfs>
|
||||
<libc stdin="/dev/terminal" stdout="/dev/terminal" stderr="/dev/log"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="counter-log">
|
||||
<binary name="test-libc_counter-source"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <log name="log2" label="2"/> </dir>
|
||||
</vfs>
|
||||
<libc stdin="/dev/log2" stdout="/dev/log2" stderr="/dev/log"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="LOG" label="2"> <child name="test-libc_component"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
</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 :
|
114
repos/libports/run/libc_vfs_component.run
Normal file
114
repos/libports/run/libc_vfs_component.run
Normal file
@ -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 {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="terminal_crosslink">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Terminal"/> </provides>
|
||||
</start>
|
||||
<start name="vfs">
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides> <service name="File_system"/> </provides>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="dev"> <terminal/> </dir>
|
||||
<dir name="tmp"> <ram/> </dir>
|
||||
</vfs>
|
||||
<default-policy root="/" writeable="yes"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="test-libc_component">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="LOG"/> </provides>
|
||||
<config ld_verbose="yes">
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
<fs/>
|
||||
</vfs>
|
||||
<libc stdin="/dev/log" stdout="/dev/log" stderr="/dev/log"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="counter-terminal">
|
||||
<binary name="test-libc_counter-source"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="dev"> <terminal/> <log/> </dir>
|
||||
</vfs>
|
||||
<libc stdin="/dev/terminal" stdout="/dev/terminal" stderr="/dev/log"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="counter-log">
|
||||
<binary name="test-libc_counter-source"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<config>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> <log name="log2" label="2"/> </dir>
|
||||
</vfs>
|
||||
<libc stdin="/dev/log2" stdout="/dev/log2" stderr="/dev/log"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="LOG" label="2"> <child name="test-libc_component"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
</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 :
|
@ -510,6 +510,7 @@ struct Libc::Kernel
|
||||
return;
|
||||
}
|
||||
|
||||
_resume_main_once = false;
|
||||
_app_returned = false;
|
||||
_app_code = &app_code;
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
175
repos/libports/src/test/libc_component/main.cc
Normal file
175
repos/libports/src/test/libc_component/main.cc
Normal file
@ -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 <base/log.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <os/static_root.h>
|
||||
#include <libc/component.h>
|
||||
#include <libc/select.h>
|
||||
#include <log_session/log_session.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
|
||||
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<Log_session>
|
||||
{
|
||||
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<Session_component> _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<Log_session> _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); }
|
3
repos/libports/src/test/libc_component/target.mk
Normal file
3
repos/libports/src/test/libc_component/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET = test-libc_component
|
||||
SRC_CC = main.cc
|
||||
LIBS = libc
|
Loading…
Reference in New Issue
Block a user