Compare commits

..

33 Commits

Author SHA1 Message Date
Jonas 'Sortie' Termansen 2239ab6271 fixup! Add strptime(3). 2023-03-22 00:04:06 +01:00
Jonas 'Sortie' Termansen 6721b7b7ce Aurora procedural wallpaper. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen d51fbffb97 Work around pty deadlock. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen 4204813d9b Add cdrom mounting live environment. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen c0bd144d66 Parallelize driver initialization. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen 898bdef447 Speed up ata(4) 400 ns waits.
Waiting for any non-zero duration currently waits for at least one timer
cycle (10 ms), which is especially expensive during early boot.

The current workaround of simply reading the status 14 times seems really
suspicious although the osdev wiki documents it, but let's see how well it
works on real hardware, it's probably good enough.

Try to determine the initial selected drive to save one drive selection.
2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen d89fd6a843 Decrease PS/2 timeouts. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen c8f6e3a072 Add uptime(1) -pr options. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen 5464b9a895 Add iso9660 filesystem implementation. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen 412c8f9892 Add kernel virtual address space usage debug information. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen 414153fab5 Revert "Update to bison-3.8.2."
This reverts commit b82fae810b42c5426d21c4dc153b32f086dd7fde.
2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen 162f82329a Update to bison-3.8.2. 2023-03-21 23:59:17 +01:00
Jonas 'Sortie' Termansen 1e82d88906 Debug TCP socket state listing. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen bd7e8f93f9 Add kernel heap allocation tracing debug facility. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen 89ca760722 Add m4, perl, and texinfo to the basic ports set. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen 75dfa634db Trianglix 4. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen c3549dc90b Add tix-check(8). 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen 884a80de75 Add automatic installer and upgrader. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen 29a4d79946 Volatile release. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen 9a3e5ee33a Add tix-upgrade(8). 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen b98d0d1f18 Add display server. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen 7f09c8ff95 Add pty(1). 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen a850e68652 Revert "Debug system calls exiting without interrupts enabled."
This reverts commit c0bc774c9aa8aa3834f40afc7ad5aa909afc61a1.
2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen b47add350e Debug system calls exiting without interrupts enabled. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen 421a074f89 Add signify port. 2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen b008298b0a Add irc(1).
Co-authored-by: Juhani Krekelä <juhani@krekelä.fi>
2023-03-21 23:59:16 +01:00
Jonas 'Sortie' Termansen f6ec5d2bc0 Add getaddrinfo(1). 2023-03-21 23:59:15 +01:00
Jonas 'Sortie' Termansen e3e5458861 Add host(1). 2023-03-21 23:59:15 +01:00
Jonas 'Sortie' Termansen 4f67aa6276 Add nginx port. 2023-03-21 23:59:15 +01:00
Jonas 'Sortie' Termansen ce5587f3a5 Enable stack smash protection by default. 2023-03-21 23:59:15 +01:00
Jonas 'Sortie' Termansen 226383ba9b Enable undefined behavior sanitization by default. 2023-03-21 23:59:15 +01:00
Jonas 'Sortie' Termansen e3ef3cfadd Add ntpd port. 2023-03-21 23:59:15 +01:00
Jonas 'Sortie' Termansen 693f57a0e3 Add strptime(3). 2023-03-21 23:59:15 +01:00
12 changed files with 249 additions and 444 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -37,8 +37,6 @@ extern "C" {
#define CLOCK_THREAD_CPUTIME_ID 8
#define CLOCK_THREAD_SYSTIME_ID 9
#define CLOCK_REALTIME_HAS_LEAP_SECONDS 1
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
#include <sortix/clock.h>
#include <sortix/fcntl.h>
#include <sortix/mman.h>
#include <sortix/stat.h>
@ -428,6 +429,70 @@ static void SystemIdleThread(void* /*user*/)
}
}
kthread_mutex_t driver_threads_lock = KTHREAD_MUTEX_INITIALIZER;
kthread_cond_t driver_threads_cond = KTHREAD_COND_INITIALIZER;
size_t driver_threads_done = 0;
size_t driver_threads_total = 0;
// Parallelize the initialization of slow drivers.
static void RunDriverThread(void (*entry)(void*), void* user, const char* name)
{
kthread_mutex_lock(&driver_threads_lock);
driver_threads_total++;
kthread_mutex_unlock(&driver_threads_lock);
if ( !RunKernelThread(entry, user, name) )
PanicF("RunKernelThread: %s", name);
}
static void FinishedDriverThread()
{
ScopedLock lock(&driver_threads_lock);
driver_threads_done++;
kthread_cond_broadcast(&driver_threads_cond);
}
struct PS2ThreadCtx
{
PS2Keyboard* keyboard;
PS2Mouse* mouse;
};
static void PS2Thread(void* user)
{
struct PS2ThreadCtx* ctx = (struct PS2ThreadCtx*) user;
PS2::Init(ctx->keyboard, ctx->mouse);
FinishedDriverThread();
}
struct DevCtx
{
Ref<Descriptor> dev;
};
static void AHCIThread(void* user)
{
AHCI::Init("/dev", ((struct DevCtx*) user)->dev);
FinishedDriverThread();
}
static void ATAThread(void* user)
{
ATA::Init("/dev", ((struct DevCtx*) user)->dev);
FinishedDriverThread();
}
static void BGAThread(void* /*user*/)
{
BGA::Init();
FinishedDriverThread();
}
static void EMThread(void* user)
{
EM::Init("/dev", ((struct DevCtx*) user)->dev);
FinishedDriverThread();
}
static void BootThread(void* /*user*/)
{
//
@ -511,6 +576,7 @@ static void BootThread(void* /*user*/)
Ref<Descriptor> slashdev = droot->open(&ctx, "dev", O_READ | O_DIRECTORY);
if ( !slashdev )
Panic("Unable to create descriptor for RAM filesystem /dev directory.");
struct DevCtx dev_ctx = { slashdev };
// Initialize the keyboard.
PS2Keyboard* keyboard = new PS2Keyboard();
@ -528,7 +594,8 @@ static void BootThread(void* /*user*/)
Panic("Could not allocate PS2 Mouse driver");
// Initialize the PS/2 controller.
PS2::Init(keyboard, mouse);
struct PS2ThreadCtx ps2_context = { keyboard, mouse };
RunDriverThread(PS2Thread, &ps2_context, "ps2");
// Register /dev/tty as the current-terminal factory.
Ref<Inode> tty(new DevTTY(slashdev->dev, 0666, 0, 0));
@ -616,13 +683,13 @@ static void BootThread(void* /*user*/)
#endif
// Initialize AHCI devices.
AHCI::Init("/dev", slashdev);
RunDriverThread(AHCIThread, &dev_ctx, "ahci");
// Initialize ATA devices.
ATA::Init("/dev", slashdev);
RunDriverThread(ATAThread, &dev_ctx, "ata");
// Initialize the BGA driver.
BGA::Init();
RunDriverThread(BGAThread, NULL, "bga");
// Initialize the filesystem network.
NetFS::Init();
@ -644,9 +711,15 @@ static void BootThread(void* /*user*/)
{
// Initialize the EM driver.
if ( enable_em )
EM::Init("/dev", slashdev);
RunDriverThread(EMThread, &dev_ctx, "em");
}
// Await the drivers initialized in the background threads.
kthread_mutex_lock(&driver_threads_lock);
while ( driver_threads_done != driver_threads_total )
kthread_cond_wait(&driver_threads_cond, &driver_threads_lock);
kthread_mutex_unlock(&driver_threads_lock);
//
// Stage 6. Executing Hosted Environment ("User-Space")
//

View File

@ -780,10 +780,6 @@ scram/scram.2 \
sys/dnsconfig/getdnsconfig.2 \
sys/dnsconfig/setdnsconfig.2 \
MANPAGES3=\
time/add_leap_seconds.3 \
time/sub_leap_seconds.3 \
HEADERS:=$(shell find include -type f)
LIBK_OBJS:=$(FREEOBJS:.o=.libk.o)
@ -910,5 +906,3 @@ install-libs-kernel: $(INSTALLLIBSKERNEL)
install-man:
mkdir -p $(DESTDIR)$(MANDIR)/man2
cp $(MANPAGES2) $(DESTDIR)$(MANDIR)/man2
mkdir -p $(DESTDIR)$(MANDIR)/man3
cp $(MANPAGES3) $(DESTDIR)$(MANDIR)/man3

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2011, 2012, 2013, 2014 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -163,9 +163,7 @@ time_t timegm(struct tm*);
#if __USE_SORTIX
int clock_gettimeres(clockid_t, struct timespec*, struct timespec*);
int clock_settimeres(clockid_t, const struct timespec*, const struct timespec*);
int timens(struct tmns*);
int sub_leap_seconds(time_t*);
int add_leap_seconds(time_t*);
int timens(struct tmns* tmns);
#endif
extern char* tzname[2];

View File

@ -1,104 +0,0 @@
.Dd March 26, 2023
.Dt ADD_LEAP_SECONDS 2
.Os
.Sh NAME
.Nm add_leap_seconds ,
.Nm sub_leap_seconds
.Nd convert between utc and tai-10 timestamps
.Sh SYNOPSIS
.In time.h
.Ft int
.Fn add_leap_seconds "time_t *timestamp"
.Ft int
.Fn sub_leap_seconds "time_t *timestamp"
.Sh DESCRIPTION
.Fn add_leap_seconds
adds leap seconds to the UTC
.Fa timestamp
to give the corresponding TAI-10 timestamp.
.Pp
.Fn sub_leap_seconds
subtracts leap seconds from the TAI-10
.Fa timestamp
to give the corresponding UTC timestamp.
.Pp
Leap seconds are announced usually six months in advanced by the
International Earth Rotation and Reference Systems Service (IERS) in Bulletin C.
Leap seconds can be added or removed at the end of the June or December (UTC)
where the last minute can be 61 or 59 seconds.
Leap seconds correct the difference between solar time and civil time when
planetary rotation varies.
Leap seconds have never been removed as of mid 2023.
.Pp
.Dv CLOCK_REALTIME
on this system is in the TAI-10 format which measures the number of actual
seconds including leap seconds that has happened since the Unix epoch of
1970-01-01 00:00:00 UTC.
The inclusion of leap seconds is advertised by the
.Dv CLOCK_REALTIME_HAS_LEAP_SECONDS
definition.
This violates POSIX's requirement that
.Dv CLOCK_REALTIME
is in UTC, which pretends leap seconds don't happen.
The
.Fn add_leap_seconds
and
.Fn sub_leap_seconds
functions are useful when exchanging timestamps with other operating systems.
.Pp
TAI-10 is International Atomic Time (TAI) subtracted by 10 seconds so the epoch
is the same moment in TAI-10 and UTC.
.Pp
TAI-10 has the advantage that every actual past moment in time has an unique and
unambiguous and continuous representation.
The time difference between two TAI-10 timestamps can be calculated as a simple
subtraction.
Durations can be simply added to TAI-10 timestamps to produce the the timestamp
changed by that many seconds.
However it's not possible to compute which TAI10 timestamp corresponds to a
calendar date and time more than 6 months in the future, as the leap seconds
have not been announced yet.
The system leap second table needs to be up to date in order to perform properly
between TAI-10 and calendar time.
TAI-10 is the most useful format when dealing with relative times, as it's
guaranteed a certain amount of time has elapsed.
.Pp
UTC has the disadvantage that two different seconds can have the same timestamp
when leap seconds are removed, and UTC can be discontinuous if a leap second
removed where a timestamp could correspond to no actual moment in time.
The actual time between two UTC timestamps cannot be computed by a simple
subtraction (a leap second table is required) and durations cannot simply be
added to wait for a particular amount of time.
UTC is the most useful format when dealing with calendar times, as it's always
possible to losslessly convert UTC to and from calendar time.
.Sh RETURN VALUES
On success 1 is returned.
.Pp
0 is returned when the input timestamp has no representation in the output
format or is ambigous.
The output timestamp will be the best approximation.
This can happen in
.Fn sub_leap_seconds
when converting from TAI-10 to UTC and a leap second has been
inserted, or in
.Fn add_leap_seconds
when converting from UTC to TAI-10 and a leap second has been removed (which has
never happened so far).
.Pp
-1 is returned when the input timestamp is too far in the future and it is
unknown whether a leap second will occur.
The output timestamp will be the best approximation.
The accurate result can be obtained when the system leap second table has been
updated.
.Sh SEE ALSO
.Xr clock_gettime 2 ,
.Xr gmtime_r 3 ,
.Xr localtime_r 3 ,
.Xr mktime 3 ,
.Xr timegm 3
.Sh HISTORY
The
.Fn add_leap_seconds
and
.Fn sub_leap_seconds
functions originally appeared in Sortix 1.1.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -23,25 +23,23 @@
#include <stdint.h>
#include <time.h>
#define DAYS_JANUARY 31
#define DAYS_FEBRUARY 28
#define DAYS_MARCH 31
#define DAYS_APRIL 30
#define DAYS_MAY 31
#define DAYS_JUNE 30
#define DAYS_JULY 31
#define DAYS_AUGUST 31
#define DAYS_SEPTEMBER 30
#define DAYS_OCTOBER 31
#define DAYS_NOVEMBER 30
#define DAYS_DECEMBER 31
#define UNKNOWN 127
static const int DAYS_JANUARY = 31;
static const int DAYS_FEBRUARY = 28;
static const int DAYS_MARCH = 31;
static const int DAYS_APRIL = 30;
static const int DAYS_MAY = 31;
static const int DAYS_JUNE = 30;
static const int DAYS_JULY = 31;
static const int DAYS_AUGUST = 31;
static const int DAYS_SEPTEMBER = 30;
static const int DAYS_OCTOBER = 31;
static const int DAYS_NOVEMBER = 30;
static const int DAYS_DECEMBER = 31;
#define DECL_LEAP_SECOND(year, jun, dec) \
{0, 0, 0, 0, 0, jun, 0, 0, 0, 0, 0, dec}
static const char leap_seconds[][12] =
static int8_t leap_seconds[][12] =
{
DECL_LEAP_SECOND(1970, 0, 0),
DECL_LEAP_SECOND(1971, 0, 0),
@ -90,47 +88,18 @@ static const char leap_seconds[][12] =
DECL_LEAP_SECOND(2014, 0, 0),
DECL_LEAP_SECOND(2015, 1, 0),
DECL_LEAP_SECOND(2016, 0, 1),
DECL_LEAP_SECOND(2017, 0, 0),
DECL_LEAP_SECOND(2018, 0, 0),
DECL_LEAP_SECOND(2019, 0, 0),
DECL_LEAP_SECOND(2020, 0, 0),
DECL_LEAP_SECOND(2021, 0, 0),
DECL_LEAP_SECOND(2022, 0, 0),
DECL_LEAP_SECOND(2023, 0, UNKNOWN),
};
static const char month_days_list[12] =
{
DAYS_JANUARY,
DAYS_FEBRUARY,
DAYS_MARCH,
DAYS_APRIL,
DAYS_MAY,
DAYS_JUNE,
DAYS_JULY,
DAYS_AUGUST,
DAYS_SEPTEMBER,
DAYS_OCTOBER,
DAYS_NOVEMBER,
DAYS_DECEMBER,
};
static time_t get_leap_second_maybe(int year, int month)
static time_t get_leap_second(int year, int month)
{
const time_t num_years = sizeof(leap_seconds) / sizeof(leap_seconds[0]);
if ( year < 1970 )
return 0;
if ( num_years <= year-1970 )
return UNKNOWN;
return 0;
return leap_seconds[year-1970][month];
}
static time_t get_leap_second(int year, int month)
{
time_t result = get_leap_second_maybe(year, month);
return result == UNKNOWN ? 0 : result;
}
static time_t leap_seconds_in_year(int year)
{
time_t ret = 0;
@ -160,11 +129,6 @@ static time_t days_in_year(int year)
DAYS_DECEMBER;
}
static int days_in_month(int year, int month)
{
return month_days_list[month] + (month == 1 && is_leap_year(year));
}
struct tm* gmtime_r(const time_t* time_ptr, struct tm* ret)
{
time_t left = *time_ptr;
@ -201,13 +165,29 @@ struct tm* gmtime_r(const time_t* time_ptr, struct tm* ret)
ret->tm_wday = (ret->tm_wday - year_days + 7*7*7*7) % 7;
}
int month_days_list[12] =
{
DAYS_JANUARY,
DAYS_FEBRUARY + (is_leap_year(ret->tm_year) ? 1 : 0),
DAYS_MARCH,
DAYS_APRIL,
DAYS_MAY,
DAYS_JUNE,
DAYS_JULY,
DAYS_AUGUST,
DAYS_SEPTEMBER,
DAYS_OCTOBER,
DAYS_NOVEMBER,
DAYS_DECEMBER,
};
// Figure out the correct month.
ret->tm_mon = 0;
ret->tm_yday = 0;
while ( true )
{
int month_leaps = get_leap_second(ret->tm_year, ret->tm_mon);
int month_days = days_in_month(ret->tm_year, ret->tm_mon);
int month_days = month_days_list[ret->tm_mon];
int month_seconds = month_days * 24 * 60 * 60 + month_leaps;
if ( month_seconds <= left )
{
@ -224,7 +204,7 @@ struct tm* gmtime_r(const time_t* time_ptr, struct tm* ret)
left = left % (24 * 60 * 60);
// If this is a regular timestamp.
if ( ret->tm_mday < days_in_month(ret->tm_year, ret->tm_mon) )
if ( ret->tm_mday < month_days_list[ret->tm_mon] )
{
ret->tm_yday += ret->tm_mday;
@ -277,10 +257,26 @@ time_t timegm(struct tm* tm)
ret += year_seconds;
}
for ( int m = 0; m < month; m++ )
int month_days_list[12] =
{
DAYS_JANUARY,
DAYS_FEBRUARY + (is_leap_year(year) ? 1 : 0),
DAYS_MARCH,
DAYS_APRIL,
DAYS_MAY,
DAYS_JUNE,
DAYS_JULY,
DAYS_AUGUST,
DAYS_SEPTEMBER,
DAYS_OCTOBER,
DAYS_NOVEMBER,
DAYS_DECEMBER,
};
for ( uint8_t m = 0; m < month; m++ )
{
int month_leaps = get_leap_second(year, m);
int month_days = days_in_month(year, m);
int month_days = month_days_list[m];
int month_seconds = month_days * 24 * 60 * 60 + month_leaps;
ret += month_seconds;
}
@ -294,58 +290,3 @@ time_t timegm(struct tm* tm)
return ret;
}
int sub_leap_seconds(time_t* ptr)
{
time_t t = *ptr;
time_t next = 0;
time_t offset = 0;
for ( int year = 1970; true; year++ )
{
for ( int month = 0; month < 12; month++ )
{
time_t seconds = days_in_month(year, month) * 24 * 60 * 60;
time_t leap = get_leap_second_maybe(year, month);
next += seconds;
if ( leap == UNKNOWN )
{
*ptr = t - offset;
return t < next - 1 ? 1 : -1;
}
next += leap;
if ( t < next )
{
*ptr = t - offset;
return 0 < leap && t + 1 == next ? 0 : 1;
}
offset += leap;
}
}
}
int add_leap_seconds(time_t* ptr)
{
time_t t = *ptr;
time_t next = 0;
time_t offset = 0;
for ( int year = 1970; true; year++ )
{
for ( int month = 0; month < 12; month++ )
{
time_t seconds = days_in_month(year, month) * 24 * 60 * 60;
time_t leap = get_leap_second_maybe(year, month);
next += seconds;
if ( leap == UNKNOWN )
{
*ptr = t + offset;
return t < next - 1 ? 1 : -1;
}
if ( t < next )
{
*ptr = t + offset;
return leap < 0 && t + 1 == next ? 0 : 1;
}
offset += leap;
}
}
}

View File

@ -1 +0,0 @@
add_leap_seconds.3

View File

@ -127,9 +127,9 @@ diff -Paur --no-dereference -- nginx.upstream/auto/install nginx/auto/install
+
+ mkdir -p '\$(DESTDIR)$NGX_SYSCONFDIR/default/passwd.d'
+ mkdir -p '\$(DESTDIR)$NGX_SYSCONFDIR/default/group.d'
+ echo "_nginx:x:101:101:_nginx:/var/empty:sh" \\
+ echo "_nginx:x:100:100:_nginx:/var/empty:sh" \\
+ > '\$(DESTDIR)$NGX_SYSCONFDIR/default/passwd.d/nginx'
+ echo "_nginx::101:_nginx" \\
+ echo "_nginx::100:_nginx" \\
+ > '\$(DESTDIR)$NGX_SYSCONFDIR/default/group.d/nginx'
END

View File

@ -80,9 +80,9 @@ diff -Paur --no-dereference -- ntpd.upstream/Makefile.in ntpd/Makefile.in
+ $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/default"
+ $(INSTALL) -m 644 "$(srcdir)/ntpd.conf" "$(DESTDIR)$(sysconfdir)/default/ntpd.conf"
+ $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/default/passwd.d"
+ echo "_ntp:x:100:100:_ntp:/var/empty:sh" > "$(DESTDIR)$(sysconfdir)/default/passwd.d/ntpd"
+ echo "_ntp:x:101:101:_ntp:/var/empty:sh" > "$(DESTDIR)$(sysconfdir)/default/passwd.d/ntpd"
+ $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/default/group.d"
+ echo "_ntp::100:_ntp" > "$(DESTDIR)$(sysconfdir)/default/group.d/ntpd"
+ echo "_ntp::101:_ntp" > "$(DESTDIR)$(sysconfdir)/default/group.d/ntpd"
uninstall-local:
- @if cmp -s "$(DESTDIR)$(sysconfdir)/ntpd.conf" "$(srcdir)/ntpd.conf"; then \
@ -134,7 +134,7 @@ diff -Paur --no-dereference -- ntpd.upstream/src/client.c ntpd/src/client.c
interval = error_interval();
set_next(p, interval);
- log_info("reply from %s: negative delay %fs, "
+ log_info("reply from %s: negative delay %lldms, "
+ log_info("reply from %s: negative delay %llims, "
"next query %llds",
log_sockaddr((struct sockaddr *)&p->addr->ss),
- p->reply[p->shift].delay, (long long)interval);
@ -148,7 +148,7 @@ diff -Paur --no-dereference -- ntpd.upstream/src/client.c ntpd/src/client.c
interval = scale_interval(INTERVAL_QUERY_NORMAL);
- log_debug("reply from %s: offset %f delay %f, "
+ log_debug("reply from %s: offset %lldms delay %lldms, "
+ log_debug("reply from %s: offset %llims delay %llims, "
"next query %llds",
log_sockaddr((struct sockaddr *)&p->addr->ss),
- offset, delay,
@ -198,27 +198,13 @@ diff -Paur --no-dereference -- ntpd.upstream/src/constraint.c ntpd/src/constrain
gettime_from_timeval(&tv[1]);
- log_info("constraint reply from %s: offset %f",
+ log_info("constraint reply from %s: offset %lld ms",
+ log_info("constraint reply from %s: offset %lli ms",
log_sockaddr((struct sockaddr *)&cstr->addr->ss),
- offset);
+ (long long)(offset * 1000));
cstr->state = STATE_REPLY_RECEIVED;
cstr->last = getmonotime();
@@ -1095,6 +1100,13 @@
/* Return parsed date as local time */
t = timegm(&httpsdate->tls_tm);
+ /* PATCH: Adjust for leap seconds in Sortix CLOCK_REALTIME. */
+#ifdef CLOCK_REALTIME_HAS_LEAP_SECONDS
+ if (!sub_leap_seconds(&t) || !sub_leap_seconds(&when.tv_sec)) {
+ return (NULL); /* Ignore during added leap second. */
+ }
+#endif
+
/* Report parsed Date: as "received time" */
rectv->tv_sec = t;
rectv->tv_usec = 0;
diff -Paur --no-dereference -- ntpd.upstream/src/control.c ntpd/src/control.c
--- ntpd.upstream/src/control.c
+++ ntpd/src/control.c
@ -247,8 +233,10 @@ diff -Paur --no-dereference -- ntpd.upstream/src/control.c ntpd/src/control.c
diff -Paur --no-dereference -- ntpd.upstream/src/init/ntpd ntpd/src/init/ntpd
--- ntpd.upstream/src/init/ntpd
+++ ntpd/src/init/ntpd
@@ -0,0 +1,2 @@
@@ -0,0 +1,4 @@
+require network
+#program=ntpd
+#exec $program -d
+exec ntpd -d
diff -Paur --no-dereference -- ntpd.upstream/src/Makefile.in ntpd/src/Makefile.in
--- ntpd.upstream/src/Makefile.in
@ -348,7 +336,7 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntp.c ntpd/src/ntp.c
diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
--- ntpd.upstream/src/ntpd.c
+++ ntpd/src/ntpd.c
@@ -45,6 +45,53 @@
@@ -45,6 +45,107 @@
#include "ntpd.h"
@ -376,6 +364,60 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
+ return 0;
+}
+
+/*
+From musl:
+
+Copyright © 2005-2014 Rich Felker, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+int daemon(int nochdir, int noclose)
+{
+ if (!nochdir && chdir("/"))
+ return -1;
+ if (!noclose) {
+ int fd, failed = 0;
+ if ((fd = open("/dev/null", O_RDWR)) < 0) return -1;
+ if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)
+ failed++;
+ if (fd > 2) close(fd);
+ if (failed) return -1;
+ }
+
+ switch(fork()) {
+ case 0: break;
+ case -1: return -1;
+ default: _exit(0);
+ }
+
+ if (setsid() < 0) return -1;
+
+ switch(fork()) {
+ case 0: break;
+ case -1: return -1;
+ default: _exit(0);
+ }
+
+ return 0;
+}
+
+int
+adjfreq(const int64_t *freq, int64_t *oldfreq)
+{
@ -402,7 +444,7 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
void sighdlr(int);
__dead void usage(void);
int auto_preconditions(const struct ntpd_conf *);
@@ -70,6 +117,7 @@
@@ -70,6 +171,7 @@
volatile sig_atomic_t sigchld = 0;
struct imsgbuf *ibuf;
int timeout = INFTIM;
@ -410,7 +452,7 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
extern u_int constraint_cnt;
@@ -108,6 +156,17 @@
@@ -108,6 +210,17 @@
}
}
@ -428,7 +470,7 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
__dead void
usage(void)
{
@@ -176,7 +235,10 @@
@@ -176,7 +289,10 @@
/* NOTREACHED */
}
@ -440,7 +482,7 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
memset(&lconf, 0, sizeof(lconf));
@@ -222,6 +284,12 @@
@@ -222,6 +338,12 @@
}
}
@ -453,63 +495,34 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
/* log to stderr until daemonized */
logdest = LOG_TO_STDERR;
if (!lconf.debug)
@@ -287,11 +355,13 @@
logdest = lconf.debug ? LOG_TO_STDERR : LOG_TO_SYSLOG;
if (!lconf.settime) {
log_init(logdest, lconf.verbose, LOG_DAEMON);
+#if 0 /* PATCH: Modern daemons must not background. */
if (!lconf.debug) {
if (daemon(1, 0))
fatal("daemon");
writepid(&lconf);
}
+#endif
} else {
settime_deadline = getmonotime();
timeout = 100;
@@ -375,11 +445,14 @@
log_init(logdest, lconf.verbose, LOG_DAEMON);
log_warnx("no reply received in time, skipping initial "
"time setting");
+#if 0
if (!lconf.debug) {
if (daemon(1, 0))
@@ -335,6 +457,10 @@
if (pledge("stdio rpath inet settime proc exec id", NULL) == -1)
err(1, "pledge");
+ if (!lconf.settime) {
+ ready();
+ }
+
while (quit == 0) {
new_cnt = PFD_MAX + constraint_cnt;
if (new_cnt > pfd_elms) {
@@ -380,6 +506,7 @@
fatal("daemon");
writepid(&lconf);
}
+#endif
+ ready();
}
if (nfds > 0 && (pfd[PFD_PIPE].revents & POLLOUT))
@@ -473,20 +546,25 @@
case IMSG_SETTIME:
if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
fatalx("invalid IMSG_SETTIME received");
- if (!lconf->settime)
+ if (!lconf->settime) {
+ ready();
break;
+ }
log_init(lconf->debug ? LOG_TO_STDERR : LOG_TO_SYSLOG,
lconf->verbose, LOG_DAEMON);
memcpy(&d, imsg.data, sizeof(d));
ntpd_settime(d);
+#if 0
/* daemonize now */
if (!lconf->debug) {
if (daemon(1, 0))
fatal("daemon");
writepid(lconf);
@@ -487,6 +614,7 @@
}
+#endif
lconf->settime = 0;
timeout = INFTIM;
+ ready();
break;
case IMSG_CONSTRAINT_QUERY:
priv_constraint_msg(imsg.hdr.peerid,
@@ -507,9 +585,8 @@
@@ -507,9 +635,8 @@
void
reset_adjtime(void)
{
@ -520,52 +533,25 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
if (adjtime(&tv, NULL) == -1)
log_warn("reset adjtime failed");
}
@@ -523,9 +600,9 @@
@@ -523,9 +650,9 @@
d += getoffset();
if (d >= threshold || d <= -1 * threshold)
- log_info("adjusting local clock by %fs", d);
+ log_info("adjusting local clock by %lldms", (long long)(d * 1000));
+ log_info("adjusting local clock by %llims", (long long)(d * 1000));
else
- log_debug("adjusting local clock by %fs", d);
+ log_debug("adjusting local clock by %lldms", (long long)(d * 1000));
+ log_debug("adjusting local clock by %llims", (long long)(d * 1000));
#ifdef HAVE_ADJTIMEX
int rc;
@@ -582,12 +659,12 @@
if (wrlog) {
if (ppmfreq >= LOG_NEGLIGIBLE_ADJFREQ ||
ppmfreq <= -LOG_NEGLIGIBLE_ADJFREQ)
- log_info("adjusting clock frequency by %f to %fppm%s",
- ppmfreq, curfreq / 1e3 / (1LL << 32),
+ log_info("adjusting clock frequency by %lld to %lldppm%s",
+ (long long)ppmfreq, (long long)(curfreq / 1e3 / (1LL << 32)),
r ? "" : " (no drift file)");
else
- log_debug("adjusting clock frequency by %f to %fppm%s",
- ppmfreq, curfreq / 1e3 / (1LL << 32),
+ log_debug("adjusting clock frequency by %lld to %lldppm%s",
+ (long long)ppmfreq, (long long)(curfreq / 1e3 / (1LL << 32)),
r ? "" : " (no drift file)");
}
@@ -610,18 +687,36 @@
return;
}
d_to_tv(d, &tv);
+#ifdef CLOCK_REALTIME_HAS_LEAP_SECONDS
+ if (!add_leap_seconds(&tv.tv_sec)) {
+ /* You finally, really did it. You maniacs! You blew it up! God damn
+ you. God damn you all to hell. */
+ return; /* Removed leap seconds have no representation here. */
+ }
+#endif
curtime.tv_usec += tv.tv_usec + 1000000;
@@ -614,14 +741,26 @@
curtime.tv_sec += tv.tv_sec - 1 + (curtime.tv_usec / 1000000);
curtime.tv_usec %= 1000000;
+#if defined(__sortix__)
+ struct timespec ts = {
+ struct timespec ts =
+ {
+ .tv_sec = curtime.tv_sec,
+ .tv_nsec = curtime.tv_usec * 1000
+ };
@ -583,60 +569,38 @@ diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
localtime(&tval));
- log_info("set local clock to %s (offset %fs)", buf, d);
+ log_info("set local clock to %s (offset %lldms)", buf, (long long)(d * 1000.0));
+ log_info("set local clock to %s (offset %llims)", buf, (long long)(d * 1000.0));
}
static FILE *freqfp;
@@ -632,6 +727,7 @@
@@ -632,6 +771,7 @@
int64_t current;
int fd;
double d;
+ long long lld;
+ long long lli;
fd = open(DRIFTFILE, O_RDWR);
if (fd == -1) {
@@ -649,7 +745,8 @@
@@ -649,7 +789,8 @@
if (adjfreq(NULL, &current) == -1)
log_warn("adjfreq failed");
else if (current == 0 && freqfp) {
- if (fscanf(freqfp, "%lf", &d) == 1) {
+ if (fscanf(freqfp, "%lld", &lld) == 1) {
+ d = (double)lld;
+ if (fscanf(freqfp, "%lli", &lli) == 1) {
+ d = (double)lli;
d /= 1e6; /* scale from ppm */
ntpd_adjfreq(d, 0);
} else
@@ -667,7 +764,8 @@
@@ -667,7 +808,8 @@
if (freqfp == NULL)
return 0;
rewind(freqfp);
- r = fprintf(freqfp, "%.3f\n", d * 1e6); /* scale to ppm */
+ long long lld = (long long)(d * 1e6);
+ r = fprintf(freqfp, "%lld\n", lld); /* scale to ppm */
+ long long lli = (long long)(d * 1e6);
+ r = fprintf(freqfp, "%lli\n", lli); /* scale to ppm */
if (r < 0 || fflush(freqfp) != 0) {
if (warnonce) {
log_warnx("can't write %s", DRIFTFILE);
@@ -901,8 +999,8 @@
clock_offset = cstatus->clock_offset < 0 ?
-1.0 * cstatus->clock_offset : cstatus->clock_offset;
if (clock_offset > 5e-7)
- printf(", clock offset is %.3fms\n",
- cstatus->clock_offset);
+ printf(", clock offset is %lldms\n",
+ (long long)cstatus->clock_offset);
else
printf("\n");
}
@@ -952,8 +1050,8 @@
(long long)cpeer->next, (long long)cpeer->poll);
if (cpeer->trustlevel >= TRUSTLEVEL_BADPEER)
- printf(" %12.3fms %9.3fms %8.3fms\n", cpeer->offset,
- cpeer->delay, cpeer->jitter);
+ printf(" %12lldms %9lldms %8lldms\n", (long long)cpeer->offset,
+ (long long)cpeer->delay, (long long)cpeer->jitter);
else
printf(" ---- peer not valid ----\n");
diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.h ntpd/src/ntpd.h
--- ntpd.upstream/src/ntpd.h
+++ ntpd/src/ntpd.h
@ -830,21 +794,12 @@ diff -Paur --no-dereference -- ntpd.upstream/src/util.c ntpd/src/util.c
double
gettime_corrected(void)
{
@@ -48,6 +50,17 @@
if (gettimeofday(&tv, NULL) == -1)
fatal("gettimeofday");
+/* PATCH: Sortix counts leap seconds in CLOCK_REALTIME but ntpd doesn't measure
+ leap seconds. Subtract them from the internal time to be UTC. */
+#ifdef CLOCK_REALTIME_HAS_LEAP_SECONDS
+ while (!sub_leap_seconds(&tv.tv_sec)) {
+ /* UTC cannot represent the current second because a leap second is
+ being inserted right now. Wait for it to pass and ignore it. */
+ sleep(1);
+ gettimeofday(&tv, NULL);
+ }
+#endif
+
return (gettime_from_timeval(&tv));
}
diff -Paur --no-dereference -- ntpd.upstream/TODO.sortix ntpd/TODO.sortix
--- ntpd.upstream/TODO.sortix
+++ ntpd/TODO.sortix
@@ -0,0 +1,5 @@
+- nptd is unaware of leap seconds but Sortix is aware of them to the clock doesn't actually get synced correctly.
+- Sortix needs `adjtime` or the time adjustments can be jarring.
+- Sortix needs `strptime`.
+- Sortix needs `getservbyname` but worked around by hard-coding the ntp port.
+- The dns process wasn't being properly killed and awaited when exiting.

View File

@ -9,4 +9,5 @@ UPSTREAM_SITE=https://ftp.openbsd.org/pub/OpenBSD/OpenNTPD
UPSTREAM_ARCHIVE=$ARCHIVE
BUILD_SYSTEM=configure
MAKE_VARS='V=1'
POST_INSTALL=tix-eradicate-libtool-la
VERSION_REGEX='([0-9]+\.[0-9]+p[0-9]+)'

View File

@ -271,17 +271,6 @@ and such.
.Dv CLOCK_REALTIME
counts the number of seconds since the epoch including leap seconds, unlike
other operating systems and in violation of POSIX.
.Dv CLOCK_REALTIME_HAS_LEAP_SECONDS
definition advertises
.Dv CLOCK_REALTIME
contains leap seconds since the epoch in the TAI-10 format.
.Pp
.Xr sub_leap_seconds 3
converts timestamps from TAI-10 to UTC by subtracting the leap seconds, while
.Xr add_leap_seconds 3
converts timestamps from UTC TO TAI-10 by adding the leap seconds.
These functions are useful when communicating with other operating systems
either via the network or exchanged data files.
.Ss u_char, u_short, u_int, u_long
.Vt unsigned char ,
.Vt unsigned short ,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2021, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2013, 2021 Jonas 'Sortie' Termansen.
* Copyright (c) 2022 Juhani 'nortti' Krekelä.
* Copyright (c) 2022 Dennis Wölfing.
*
@ -19,8 +19,6 @@
* Print or set system date and time.
*/
#include <sys/stat.h>
#include <err.h>
#include <stdbool.h>
#include <stdint.h>
@ -52,18 +50,13 @@ static char* astrftime(const char* format, const struct tm* tm)
int main(int argc, char* argv[])
{
const char* date = NULL;
bool set = false;
const char* reference = NULL;
const char* format = "+%a %b %e %H:%M:%S %Z %Y";
int opt;
while ( (opt = getopt(argc, argv, "d:r:s:u")) != -1 )
while ( (opt = getopt(argc, argv, "u")) != -1 )
{
switch ( opt )
{
case 'd': date = optarg; break;
case 'r': reference = optarg; break;
case 's': date = optarg; set = true; break;
case 'u':
if ( setenv("TZ", "UTC0", 1) )
err(1, "setenv");
@ -72,52 +65,20 @@ int main(int argc, char* argv[])
}
}
if ( date && reference )
errx(1, "the -d and -r options are mutually incompatible");
if ( set && reference )
errx(1, "the -s and -r options are mutually incompatible");
const char* format = "+%a %b %e %H:%M:%S %Z %Y";
if ( 1 <= argc - optind )
{
if ( argv[optind][0] != '+' )
errx(1, "the format specifier must start with a +");
errx(1, "setting the system time is not implemented");
format = argv[optind];
}
if ( 2 <= argc - optind )
errx(1, "unexpected extra operand: %s", argv[optind + 1]);
struct timespec moment = {0};
struct tm tm = {0};
time_t current_time = time(NULL);
if ( date )
{
memset(&tm, 0, sizeof(tm));
if ( !strptime(date, format + 1, &tm) )
errx(1, "date didn't match %s: %s", format + 1, date);
moment.tv_sec = timegm(&tm); // TODO: timelocal
}
else
{
if ( reference )
{
struct stat st;
if ( stat(reference, &st) < 0 )
err(1, "%s", reference);
moment = st.st_mtim;
}
else
clock_gettime(CLOCK_REALTIME, &moment);
if ( !localtime_r(&moment.tv_sec, &tm) )
err(1, "localtime_r(%ji)", (intmax_t) moment.tv_sec);
}
if ( set )
{
if ( clock_settime(CLOCK_REALTIME, &moment) < 0 )
err(1, "clock_settime: CLOCK_REALTIME");
return 0;
}
struct tm tm;
if ( !localtime_r(&current_time, &tm) )
err(1, "localtime_r(%ji)", (intmax_t) current_time);
char* string = astrftime(format, &tm);
if ( !string )