libc: prevent timer session if rtc not configured

This patch makes the creation of the libc's timer session depend on
whether or not the 'rtc' attribute of the <libc> configuration is
defined. If not configured, 'clock_gettime' returns 0.

Fixes #2625
This commit is contained in:
Norman Feske 2017-12-20 12:11:11 +01:00 committed by Christian Helmuth
parent d873c13e16
commit 1be4a0aeaf
7 changed files with 85 additions and 97 deletions

View File

@ -11,8 +11,8 @@ LIBS += base vfs
# Back end
#
SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc \
issetugid.cc errno.cc gai_strerror.cc clock_gettime.cc \
gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \
issetugid.cc errno.cc gai_strerror.cc time.cc \
malloc.cc progname.cc fd_alloc.cc file_operations.cc \
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
pread_pwrite.cc readv_writev.cc poll.cc \
libc_pdbg.cc vfs_plugin.cc rtc.cc dynamic_linker.cc signal.cc \

View File

@ -87,7 +87,7 @@ append config {
<resource name="RAM" quantum="4M"/>
<config>
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="dev"> <log/> <inline name="rtc">2018-01-01 00:01</inline> </dir>
<dir name="ifd-ccid.bundle">
<dir name="Contents">
<rom name="Info.plist"/>
@ -97,7 +97,7 @@ append config {
<config vendor_id="0x04e6" product_id="0x5116"/>
</inline>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log"/>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
</config>
</start>
</config>}

View File

@ -1,44 +0,0 @@
/*
* \brief C-library back end
* \author Christian Prochaska
* \date 2010-05-19
*/
/*
* Copyright (C) 2010-2017 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>
#include "task.h"
namespace Libc { time_t read_rtc(); }
extern "C" __attribute__((weak))
int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
if (!tp) return 0;
static bool read_rtc = false;
static time_t rtc = 0;
static unsigned long t0 = 0;
if (!read_rtc) {
rtc = Libc::read_rtc();
read_rtc = true;
t0 = Libc::current_time();
}
unsigned long time = Libc::current_time() - t0;
tp->tv_sec = rtc + time/1000;
tp->tv_nsec = (time % 1000) * (1000*1000);
return 0;
}

View File

@ -1,44 +0,0 @@
/*
* \brief C-library back end
* \author Norman Feske
* \date 2008-11-11
*/
/*
* Copyright (C) 2008-2017 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>
#include "task.h"
namespace Libc { time_t read_rtc(); }
extern "C" __attribute__((weak))
int gettimeofday(struct timeval *tv, struct timezone *)
{
if (!tv) return 0;
static bool read_rtc = false;
static time_t rtc = 0;
static unsigned long t0 = 0;
if (!read_rtc) {
rtc = Libc::read_rtc();
read_rtc = true;
t0 = Libc::current_time();
}
unsigned long time = Libc::current_time() - t0;
tv->tv_sec = rtc + time/1000;
tv->tv_usec = (time % 1000) * 1000;
return 0;
}

View File

@ -11,7 +11,7 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/printf.h>
#include <base/log.h>
#include <util/string.h>
#include <sys/stat.h>
@ -32,13 +32,13 @@ time_t Libc::read_rtc()
time_t rtc = 0;
if (!Genode::strcmp(Libc::config_rtc(), "")) {
PWRN("%s: rtc not configured, returning %lld", __func__, (long long)rtc);
Genode::warning("rtc not configured, returning ", rtc);
return rtc;
}
int fd = open(Libc::config_rtc(), O_RDONLY);
if (fd == -1) {
PWRN("%s: %s not readable, returning %lld", __func__, Libc::config_rtc(), (long long)rtc);
Genode::warning(Genode::Cstring(Libc::config_rtc()), " not readable, returning ", rtc);
return rtc;
}

View File

@ -0,0 +1,71 @@
/*
* \brief C-library back end
* \author Christian Prochaska
* \author Norman Feske
* \date 2010-05-19
*/
/*
* Copyright (C) 2010-2017 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>
#include "task.h"
#include "libc_errno.h"
namespace Libc { time_t read_rtc(); }
extern "C" __attribute__((weak))
int clock_gettime(clockid_t clk_id, struct timespec *ts)
{
if (!ts) return 0;
static bool initial_rtc_requested = false;
static time_t initial_rtc = 0;
static unsigned long t0 = 0;
ts->tv_sec = 0;
ts->tv_nsec = 0;
/* try to read rtc once */
if (!initial_rtc_requested) {
initial_rtc_requested = true;
initial_rtc = Libc::read_rtc();
if (initial_rtc)
t0 = Libc::current_time();
}
if (!initial_rtc)
return Libc::Errno(EINVAL);
unsigned long time = Libc::current_time() - t0;
ts->tv_sec = initial_rtc + time/1000;
ts->tv_nsec = (time % 1000) * (1000*1000);
return 0;
}
extern "C" __attribute__((weak))
int gettimeofday(struct timeval *tv, struct timezone *)
{
if (!tv) return 0;
struct timespec ts;
if (int ret = clock_gettime(0, &ts))
return ret;
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / 1000;
return 0;
}

View File

@ -224,6 +224,7 @@ append_if $use_wifi_driver config {
<log/>
<jitterentropy name="random"/>
<jitterentropy name="urandom"/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="config"> <fs label="config"/> </dir>
</vfs>
@ -253,8 +254,12 @@ append config {
<libc tx_buf_size="2M" rx_buf_size="2M"}
append_if [have_spec linux] config " ip_addr=\"$lx_ip_addr\" netmask=\"255.255.255.0\" gateway=\"10.0.2.1\""
append config {
stdout="/dev/log" stderr="/dev/log"/>
<vfs> <dir name="dev"> <log/> </dir> </vfs>
stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
<vfs>
<dir name="dev">
<log/> <inline name="rtc">2018-01-01 00:01</inline>
</dir>
</vfs>
</config>}
append_if $use_nic_bridge config {
<route>