mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 13:26:27 +00:00
libc: rudimentary support for SIGALRM
This patch enables basic use cases of the POSIX 'alarm' function, which schedules the delivery of a SIGALRM signal after a specified amount of seconds. Issue #5337
This commit is contained in:
parent
0a178dc625
commit
fc3bd14da0
@ -681,6 +681,7 @@ set default_test_pkgs {
|
||||
test-libc_fifo_pipe
|
||||
test-libc_fork
|
||||
test-libc_getenv
|
||||
test-libc_alarm
|
||||
test-libc_pipe
|
||||
test-libc_vfs
|
||||
test-libc_vfs_audit
|
||||
|
@ -12,7 +12,7 @@ LIBS += base vfs
|
||||
# Back end
|
||||
#
|
||||
SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc \
|
||||
issetugid.cc errno.cc gai_strerror.cc time.cc \
|
||||
issetugid.cc errno.cc gai_strerror.cc time.cc alarm.cc \
|
||||
malloc.cc progname.cc fd_alloc.cc file_operations.cc \
|
||||
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc sleep.cc \
|
||||
pread_pwrite.cc readv_writev.cc poll.cc \
|
||||
|
1
repos/libports/recipes/pkg/test-libc_alarm/README
Normal file
1
repos/libports/recipes/pkg/test-libc_alarm/README
Normal file
@ -0,0 +1 @@
|
||||
Libc alarm() test.
|
5
repos/libports/recipes/pkg/test-libc_alarm/archives
Normal file
5
repos/libports/recipes/pkg/test-libc_alarm/archives
Normal file
@ -0,0 +1,5 @@
|
||||
_/src/init
|
||||
_/src/test-libc_alarm
|
||||
_/src/libc
|
||||
_/src/posix
|
||||
_/src/vfs
|
1
repos/libports/recipes/pkg/test-libc_alarm/hash
Normal file
1
repos/libports/recipes/pkg/test-libc_alarm/hash
Normal file
@ -0,0 +1 @@
|
||||
2024-08-30 ca6e62da4a88ade9338dea365858d83409150c78
|
22
repos/libports/recipes/pkg/test-libc_alarm/runtime
Normal file
22
repos/libports/recipes/pkg/test-libc_alarm/runtime
Normal file
@ -0,0 +1,22 @@
|
||||
<runtime ram="3M" caps="200" binary="test-libc_alarm">
|
||||
|
||||
<requires> <timer/> </requires>
|
||||
|
||||
<fail after_seconds="13"/>
|
||||
<succeed>triggered_alarms=3</succeed>
|
||||
|
||||
<content>
|
||||
<rom label="ld.lib.so"/>
|
||||
<rom label="test-libc_alarm"/>
|
||||
<rom label="libc.lib.so"/>
|
||||
<rom label="libm.lib.so"/>
|
||||
<rom label="vfs.lib.so"/>
|
||||
<rom label="posix.lib.so"/>
|
||||
</content>
|
||||
|
||||
<config>
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log"/>
|
||||
<arg value="test-libc_alarm"/>
|
||||
</config>
|
||||
</runtime>
|
2
repos/libports/recipes/src/test-libc_alarm/content.mk
Normal file
2
repos/libports/recipes/src/test-libc_alarm/content.mk
Normal file
@ -0,0 +1,2 @@
|
||||
SRC_DIR := src/test/libc_alarm
|
||||
include $(GENODE_DIR)/repos/base/recipes/src/content.inc
|
1
repos/libports/recipes/src/test-libc_alarm/hash
Normal file
1
repos/libports/recipes/src/test-libc_alarm/hash
Normal file
@ -0,0 +1 @@
|
||||
2024-08-30 49e1a2b9ef6049be7c0fcee964324fbda54cbed7
|
2
repos/libports/recipes/src/test-libc_alarm/used_apis
Normal file
2
repos/libports/recipes/src/test-libc_alarm/used_apis
Normal file
@ -0,0 +1,2 @@
|
||||
libc
|
||||
posix
|
118
repos/libports/src/lib/libc/alarm.cc
Normal file
118
repos/libports/src/lib/libc/alarm.cc
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* \brief Libc interval timer
|
||||
* \author Norman Feske
|
||||
* \date 2024-08-00
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/time.h>
|
||||
|
||||
/* libc-internal includes */
|
||||
#include <internal/signal.h>
|
||||
#include <internal/timer.h>
|
||||
#include <internal/init.h>
|
||||
#include <internal/errno.h>
|
||||
|
||||
|
||||
static Libc::Timer_accessor *_timer_accessor_ptr;
|
||||
static Libc::Signal *_signal_ptr;
|
||||
|
||||
void Libc::init_alarm(Timer_accessor &timer_accessor, Signal &signal)
|
||||
{
|
||||
_timer_accessor_ptr = &timer_accessor;
|
||||
_signal_ptr = &signal;
|
||||
}
|
||||
|
||||
|
||||
namespace Libc { struct Itimer_real; }
|
||||
|
||||
|
||||
struct Libc::Itimer_real : Noncopyable
|
||||
{
|
||||
struct Handler : Timeout_handler
|
||||
{
|
||||
Signal &_signal;
|
||||
|
||||
virtual void handle_timeout() override { _signal.charge(SIGALRM); }
|
||||
|
||||
Handler(Signal &signal) : _signal(signal) { }
|
||||
|
||||
} _handler;
|
||||
|
||||
Timer_accessor &_timer_accessor;
|
||||
|
||||
Constructible<Timeout> _timeout { };
|
||||
|
||||
void arm_or_disarm(timeval tv)
|
||||
{
|
||||
Libc::uint64_t const ms = tv.tv_sec*1000 + tv.tv_usec/1000;
|
||||
|
||||
if (ms) {
|
||||
_timeout.construct(_timer_accessor, _handler);
|
||||
_timeout->start(ms);
|
||||
} else {
|
||||
_timeout.destruct();
|
||||
}
|
||||
}
|
||||
|
||||
timeval current()
|
||||
{
|
||||
if (!_timeout.constructed())
|
||||
return { };
|
||||
|
||||
Libc::uint64_t const ms = _timeout->duration_left();
|
||||
|
||||
return { .tv_sec = long(ms/1000),
|
||||
.tv_usec = long((ms % 1000)*1000) };
|
||||
}
|
||||
|
||||
Itimer_real(Timer_accessor &timer_accessor, Signal &signal)
|
||||
:
|
||||
_handler(signal), _timer_accessor(timer_accessor)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
using namespace Libc;
|
||||
|
||||
|
||||
static Itimer_real &itimer_real()
|
||||
{
|
||||
struct Missing_call_of_init_alarm : Exception { };
|
||||
if (!_timer_accessor_ptr || !_signal_ptr)
|
||||
throw Missing_call_of_init_alarm();
|
||||
|
||||
static Itimer_real itimer { *_timer_accessor_ptr, *_signal_ptr };
|
||||
return itimer;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int setitimer(int which, const itimerval *new_value, itimerval *old_value)
|
||||
{
|
||||
if (which != ITIMER_REAL) {
|
||||
warning("setitimer: timer %d unsupported");
|
||||
return Errno(EINVAL);
|
||||
}
|
||||
|
||||
if (!new_value)
|
||||
return Errno(EFAULT);
|
||||
|
||||
if (new_value->it_interval.tv_sec || new_value->it_interval.tv_usec)
|
||||
warning("setitimer: argument 'new_value->it_interval' not handled");
|
||||
|
||||
if (old_value) {
|
||||
old_value->it_interval = { };
|
||||
old_value->it_value = itimer_real().current();
|
||||
}
|
||||
|
||||
itimer_real().arm_or_disarm(new_value->it_value);
|
||||
|
||||
return 0;
|
||||
}
|
@ -141,7 +141,6 @@ DUMMY(int , -1, seteuid, (uid_t))
|
||||
DUMMY(int , -1, setgid, (gid_t))
|
||||
DUMMY(int , -1, setuid, (uid_t))
|
||||
DUMMY(int , -1, setgroups, (int, const gid_t *))
|
||||
DUMMY(int , -1, setitimer, (int, const itimerval *, itimerval *))
|
||||
DUMMY(int , -1, setpgid, (pid_t, pid_t))
|
||||
DUMMY(int , -1, setpriority, (int, int, int))
|
||||
DUMMY(int , -1, setregid, (gid_t, gid_t))
|
||||
|
@ -108,6 +108,7 @@ namespace Libc {
|
||||
*/
|
||||
void init_sleep(Monitor &);
|
||||
void init_time(Current_time &, Current_real_time &);
|
||||
void init_alarm(Timer_accessor &, Signal &);
|
||||
|
||||
/**
|
||||
* Socket fs
|
||||
|
@ -16,10 +16,13 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/noncopyable.h>
|
||||
#include <util/reconstructible.h>
|
||||
#include <base/registry.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* libc-internal includes */
|
||||
#include <internal/call_func.h>
|
||||
|
@ -508,6 +508,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
|
||||
init_vfs_plugin(*this, _env.rm());
|
||||
init_file_operations(*this, _libc_env);
|
||||
init_time(*this, *this);
|
||||
init_alarm(_timer_accessor, _signal);
|
||||
init_poll(_signal, *this);
|
||||
init_select(*this);
|
||||
init_socket_fs(*this, *this);
|
||||
|
52
repos/libports/src/test/libc_alarm/main.c
Normal file
52
repos/libports/src/test/libc_alarm/main.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* \brief Libc alarm test
|
||||
* \author Norman Feske
|
||||
* \date 2024-08-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static unsigned triggered_alarms;
|
||||
|
||||
static void sigalarm_handler(int)
|
||||
{
|
||||
triggered_alarms++;
|
||||
}
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
static struct sigaction sa;
|
||||
sa.sa_handler = sigalarm_handler;
|
||||
|
||||
int ret = sigaction(SIGALRM, &sa, NULL);
|
||||
if (ret < 0) {
|
||||
printf("sigaction unexpectedly returned %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
signal(SIGALRM, sigalarm_handler);
|
||||
|
||||
unsigned observed_alarms = 0;
|
||||
|
||||
alarm(2);
|
||||
|
||||
while (observed_alarms != 3) {
|
||||
sleep(1);
|
||||
printf("triggered_alarms=%u\n", triggered_alarms);
|
||||
|
||||
if (triggered_alarms != observed_alarms) {
|
||||
observed_alarms = triggered_alarms;
|
||||
alarm(2);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
3
repos/libports/src/test/libc_alarm/target.mk
Normal file
3
repos/libports/src/test/libc_alarm/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET = test-libc_alarm
|
||||
SRC_C = main.c
|
||||
LIBS = posix
|
Loading…
Reference in New Issue
Block a user