libc/time: Add CLOCK_TAI

Message ID 20250711024932.16275-1-sebastian.huber@embedded-brains.de
State New
Headers
Series libc/time: Add CLOCK_TAI |

Commit Message

Sebastian Huber July 11, 2025, 2:49 a.m. UTC
  For _GNU_VISIBLE, provide the CLOCK_TAI clock identifier for the
International Atomic Time.  Use the value specified by glibc and Linux.
---
 newlib/libc/include/time.h | 2 ++
 1 file changed, 2 insertions(+)
  

Comments

Sebastian Huber July 11, 2025, 4:35 a.m. UTC | #1
Hallo,

FreeBSD also provides this clock identifier, maybe it should be

#if __BSD_VISIBLE

#define CLOCK_TAI		(11)

#endif

?
  
Corinna Vinschen July 14, 2025, 3:45 p.m. UTC | #2
On Jul 11 06:35, Sebastian Huber wrote:
> Hallo,
> 
> FreeBSD also provides this clock identifier, maybe it should be
> 
> #if __BSD_VISIBLE
> 
> #define CLOCK_TAI		(11)
> 
> #endif
> 
> ?

Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.

IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
return the same value, because the leap second is set to 0 at kernel
startup.  Maybe that's enough...


Corinna
  
Brian Inglis July 14, 2025, 8:38 p.m. UTC | #3
On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
> On Jul 11 06:35, Sebastian Huber wrote:
>> FreeBSD also provides this clock identifier, maybe it should be
>> #if __BSD_VISIBLE
>> #define CLOCK_TAI		(11)
>> #endif
>> ?

> Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.

> IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
> return the same value, because the leap second is set to 0 at kernel
> startup.  Maybe that's enough...

If you are running an NTP server you just have to ask for the system variable:

$ ntpq -c'rv 0 tai'
tai=37
$ ntpq -c'rv 0 tai,leapsec,expire'
tai=37, leapsec=201701010000, expire=202606280000

assuming you keep it updated from IERS, NIST, and/or USNO upstreams.

Or install tzdata-right to get leapsecond compensated timezones at TAI-10s:

$ ntptime.sh; TZ=right/UTC date +%c%z; date -u +%c%z; TZ=right/$TZ date +%c%z; 
date +%c%z
2025 Jul 14 Mon 20:15:33+0000  JD 2460871.344132  MJD 60870.844132  ToD 72933
NTP 3961512933  Unix 1752524133  TAI-UTC 37  TAI-GPS 19  GPS-UTC 18
GPS We 2375  Cy 2 Wn 327  Wa 71  ToW 159351  DoW 1 ToD 72951
2025 Jul 14 Mon 20:15:06+0000
2025 Jul 14 Mon 20:15:33+0000
2025 Jul 14 Mon 14:15:06-0600
2025 Jul 14 Mon 14:15:33-0600

These are updated with every IERS Bulletin C leapsecond announcement and data 
update, made available in the next tzdata release.
  
Corinna Vinschen July 15, 2025, 8:43 a.m. UTC | #4
On Jul 14 14:38, Brian Inglis via Newlib wrote:
> On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
> > On Jul 11 06:35, Sebastian Huber wrote:
> > > FreeBSD also provides this clock identifier, maybe it should be
> > > #if __BSD_VISIBLE
> > > #define CLOCK_TAI		(11)
> > > #endif
> > > ?
> 
> > Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.
> 
> > IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
> > return the same value, because the leap second is set to 0 at kernel
> > startup.  Maybe that's enough...
> 
> If you are running an NTP server you just have to ask for the system variable:
> 
> $ ntpq -c'rv 0 tai'
> tai=37
> $ ntpq -c'rv 0 tai,leapsec,expire'
> tai=37, leapsec=201701010000, expire=202606280000
> 
> assuming you keep it updated from IERS, NIST, and/or USNO upstreams.
> 
> Or install tzdata-right to get leapsecond compensated timezones at TAI-10s:
> 
> $ ntptime.sh; TZ=right/UTC date +%c%z; date -u +%c%z; TZ=right/$TZ date
> +%c%z; date +%c%z
> 2025 Jul 14 Mon 20:15:33+0000  JD 2460871.344132  MJD 60870.844132  ToD 72933
> NTP 3961512933  Unix 1752524133  TAI-UTC 37  TAI-GPS 19  GPS-UTC 18
> GPS We 2375  Cy 2 Wn 327  Wa 71  ToW 159351  DoW 1 ToD 72951
> 2025 Jul 14 Mon 20:15:06+0000
> 2025 Jul 14 Mon 20:15:33+0000
> 2025 Jul 14 Mon 14:15:06-0600
> 2025 Jul 14 Mon 14:15:33-0600
> 
> These are updated with every IERS Bulletin C leapsecond announcement and
> data update, made available in the next tzdata release.

I read up on leap secs and TAI yesterday, and it seems Linux is not doing
as lot by itself (i.e., the kernel).  Also, leap secs are pretty static,
especially since 2017. We had no leap sec since that time anymore, so we're
on a 37 sec shift for ~8 years.

We need some way to handle that without extra packages.  Ideally this is
between the Cygwin DLL and the OS with no extra layer between them.
Unfortunately I didn't find a Windows API to ask the OS for the current
leap secs offset.

What we could do is to define CLOCK_TAI as CLOCK_REALTIME + 37 in the DLL
for the time being, and the DLL could check if a file "/etc/leapsecs"
exists and read it to compensate for new leap secs.  We can add such a
file to the distro when a new leap sec has been defined.

So, yeah, we can just add CLOCK_TAI and we add that functionality to
the Cygwin DLL for the 3.7 release cycle. Shouldn't be too much work.

So, Sebastian, just go ahead defining CLOCK_TAI.  A __BSD_VISIBLE
guard seems like a good idea.  Maybe adding a `|| _GNU_VISIBLE' for
readability, even if that's redundant...


Thanks,
Corinna
  
Howland, Craig D. - US via Newlib July 15, 2025, 9:01 p.m. UTC | #5
On 2025-07-15 02:43, Corinna Vinschen via Newlib wrote:
> On Jul 14 14:38, Brian Inglis via Newlib wrote:
>> On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
>>> On Jul 11 06:35, Sebastian Huber wrote:
>>>> FreeBSD also provides this clock identifier, maybe it should be
>>>> #if __BSD_VISIBLE
>>>> #define CLOCK_TAI		(11)
>>>> #endif
>>>> ?
>>
>>> Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.
>>
>>> IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
>>> return the same value, because the leap second is set to 0 at kernel
>>> startup.  Maybe that's enough...
>>
>> If you are running an NTP server you just have to ask for the system variable:
>>
>> $ ntpq -c'rv 0 tai'
>> tai=37
>> $ ntpq -c'rv 0 tai,leapsec,expire'
>> tai=37, leapsec=201701010000, expire=202606280000
>>
>> assuming you keep it updated from IERS, NIST, and/or USNO upstreams.
>>
>> Or install tzdata-right to get leapsecond compensated timezones at TAI-10s:
>>
>> $ ntptime.sh; TZ=right/UTC date +%c%z; date -u +%c%z; TZ=right/$TZ date
>> +%c%z; date +%c%z
>> 2025 Jul 14 Mon 20:15:33+0000  JD 2460871.344132  MJD 60870.844132  ToD 72933
>> NTP 3961512933  Unix 1752524133  TAI-UTC 37  TAI-GPS 19  GPS-UTC 18
>> GPS We 2375  Cy 2 Wn 327  Wa 71  ToW 159351  DoW 1 ToD 72951
>> 2025 Jul 14 Mon 20:15:06+0000
>> 2025 Jul 14 Mon 20:15:33+0000
>> 2025 Jul 14 Mon 14:15:06-0600
>> 2025 Jul 14 Mon 14:15:33-0600
>>
>> These are updated with every IERS Bulletin C leapsecond announcement and
>> data update, made available in the next tzdata release.
> 
> I read up on leap secs and TAI yesterday, and it seems Linux is not doing
> as lot by itself (i.e., the kernel).  Also, leap secs are pretty static,
> especially since 2017. We had no leap sec since that time anymore, so we're
> on a 37 sec shift for ~8 years.
> 
> We need some way to handle that without extra packages.  Ideally this is
> between the Cygwin DLL and the OS with no extra layer between them.
> Unfortunately I didn't find a Windows API to ask the OS for the current
> leap secs offset.
> 
> What we could do is to define CLOCK_TAI as CLOCK_REALTIME + 37 in the DLL
> for the time being, and the DLL could check if a file "/etc/leapsecs"
> exists and read it to compensate for new leap secs.  We can add such a
> file to the distro when a new leap sec has been defined.

It may be better to just use the standard approach and standard file name which 
is /etc/leap-seconds.list, often symlinked from /etc/ntp/ which may itself be 
symlinked from /var/lib/ntp/.

Fedora chrony (RH default ntp implementation alternative) relies on Fedora 
tzdata to provide it, as the IERS upstream is included in the sources, and it is 
installed in /usr/share/zoneinfo, with the tzdata processed format leapseconds.

	https://src.fedoraproject.org/rpms/chrony/blob/main/f/chrony.spec
	https://src.fedoraproject.org/rpms/tzdata/blob/main/f/tzdata.spec
	https://src.fedoraproject.org/rpms/ntpsec/blob/main/f/ntpsec.spec

I could do the same in Cygwin tzdata, installing symlink(s) as above, leading 
back to /etc/leap-seconds.list, via any intermediates deemed necessary.

The dev tzdata sources are available from:

	https://github.com/eggert/tz

	https://github.com/eggert/tz/blob/main/leap-seconds.list

and the last non-comment line contains the current TAI offset and effective date 
as the NTP time stamp (NTP epoch is 1900-01-01 00:00:00Z so that offset from 
UNIX epoch can be added to convert):

	$ grep '^[^#]' /etc/leap-seconds.list | tail -1
	3692217600      37      # 1 Jan 2017
	$ date -u -d'1900-01-01 00:00:00+0000' +%s
	-2208988800
	$ date -u -d'1900-01-01 00:00:00+0000 + 3692217600 seconds'
	2017 Jan 01 Sun 00:00:00
> So, yeah, we can just add CLOCK_TAI and we add that functionality to
> the Cygwin DLL for the 3.7 release cycle. Shouldn't be too much work.
> 
> So, Sebastian, just go ahead defining CLOCK_TAI.  A __BSD_VISIBLE
> guard seems like a good idea.  Maybe adding a `|| _GNU_VISIBLE' for
> readability, even if that's redundant...
I run [Meinberg] ntpd/ntpq not w32tm, but another system shows:

 > w32tm /query /status /verbose
Leap Indicator: 0(no warning)
Stratum: 2 (secondary reference - syncd by (S)NTP)
Precision: -23 (119.209ns per tick)
Root Delay: 0.0561072s
Root Dispersion: 7.7939052s
ReferenceId: 0xD8C5E4E6 (source IP:  216.197.228.230)
Last Successful Sync Time: 2025-07-15 7:31:24 AM
Source: 0.ca.pool.ntp.org
Poll Interval: 15 (32768s)

Phase Offset: -0.0022481s
ClockRate: 0.0156250s
State Machine: 2 (Sync)
Time Source Flags: 0 (None)
Server Role: 576 (Reliable Time Service)
Last Sync Error: 2 (The computer did not resync because only stale time data was 
available.)

Time since Last Good Sync Time: 19676.7457267s

 > w32tm /leapseconds /getstatus /verbose

[Leap Seconds]
Enabled: 1 (Local)
Number of Leap Seconds (after June 2018): 0 (Local)
Leap Seconds List (Local):

https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings

https://techcommunity.microsoft.com/blog/networkingblog/top-10-networking-features-in-windows-server-2019-10-accurate-network-time/339739

https://techcommunity.microsoft.com/blog/networkingblog/leap-seconds-for-the-it-pro-what-you-need-to-know/339811

and w32tm updates allow leapseconds to be added and removed:

	https://github.com/microsoft/STL/discussions/1624

Updates may be visible at:

	https://microsoft.visualstudio.com/OS/_workitems/edit/32341669

 > w32tm /leapseconds /add:+2021-11-30T23:59:59 /force
The command completed successfully.

 > w32tm /leapseconds /getstatus /verbose
[Leap Seconds]
Enabled: 1 (Local)
Number of Leap Seconds (after June 2018): 1 (Local)
Leap Seconds List (Local):
+2021-11-30T23:59:59

 > w32tm /leapseconds /remove:+2021-11-30T23:59:59 /force
The command completed successfully.

My ntp server shows:

w32tm /stripchart /computer:localhost /dataonly /samples:10
Tracking localhost [[::1]:123].
Collecting 10 samples.
The current time is 2025-07-15 14:40:20.
14:40:20, -00.0000115s
14:40:22, +00.0001352s
14:40:24, +00.0001355s
14:40:26, +00.0001052s
14:40:28, +00.0000881s
14:40:30, +00.0000685s
14:40:32, +00.0000758s
14:40:34, +00.0000872s
14:40:36, +00.0000662s
14:40:38, +00.0000380s

 > w32tm /stripchart /computer:localhost /dataonly /samples:10 /rdtsc
Tracking localhost [[::1]:123].
Collecting 10 samples.
The current time is 2025-07-15 14:39:58.
RdtscStart, RdtscEnd, FileTime, RoundtripDelay, NtpOffset
2170263874159491, 2170263877515570, 133970855987299848, +00.0005957, +00.0000436
2170270901868499, 2170270904970262, 133970856007416482, +00.0003988, +00.0001364
2170277901548544, 2170277905644173, 133970856027452949, +00.0004523, +00.0001429
2170284903885522, 2170284907988833, 133970856047496959, +00.0006049, +00.0001642
2170291958659606, 2170291962514063, 133970856067691066, +00.0005711, +00.0000280
2170298960387316, 2170298964954578, 133970856087733330, +00.0007743, +00.0000636
2170305962010214, 2170305965895147, 133970856107775354, +00.0003717, +00.0001210
2170312965127357, 2170312969730343, 133970856127821599, +00.0007545, +00.0000768
2170319970032844, 2170319973530838, 133970856147872961, +00.0004328, +00.0001321
2170326974367562, 2170326978138033, 133970856167922687, +00.0004454, +00.0001380
  
Brian Inglis July 15, 2025, 9:33 p.m. UTC | #6
On 2025-07-15 15:01, brian.inglis--- via Newlib wrote:
> On 2025-07-15 02:43, Corinna Vinschen via Newlib wrote:
>> On Jul 14 14:38, Brian Inglis via Newlib wrote:
>>> On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
>>>> On Jul 11 06:35, Sebastian Huber wrote:
>>>>> FreeBSD also provides this clock identifier, maybe it should be
>>>>> #if __BSD_VISIBLE
>>>>> #define CLOCK_TAI        (11)
>>>>> #endif
>>>>> ?
>>>
>>>> Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.
>>>
>>>> IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
>>>> return the same value, because the leap second is set to 0 at kernel
>>>> startup.  Maybe that's enough...
>>>
>>> If you are running an NTP server you just have to ask for the system variable:
>>>
>>> $ ntpq -c'rv 0 tai'
>>> tai=37
>>> $ ntpq -c'rv 0 tai,leapsec,expire'
>>> tai=37, leapsec=201701010000, expire=202606280000
>>>
>>> assuming you keep it updated from IERS, NIST, and/or USNO upstreams.
>>>
>>> Or install tzdata-right to get leapsecond compensated timezones at TAI-10s:
>>>
>>> $ ntptime.sh; TZ=right/UTC date +%c%z; date -u +%c%z; TZ=right/$TZ date
>>> +%c%z; date +%c%z
>>> 2025 Jul 14 Mon 20:15:33+0000  JD 2460871.344132  MJD 60870.844132  ToD 72933
>>> NTP 3961512933  Unix 1752524133  TAI-UTC 37  TAI-GPS 19  GPS-UTC 18
>>> GPS We 2375  Cy 2 Wn 327  Wa 71  ToW 159351  DoW 1 ToD 72951
>>> 2025 Jul 14 Mon 20:15:06+0000
>>> 2025 Jul 14 Mon 20:15:33+0000
>>> 2025 Jul 14 Mon 14:15:06-0600
>>> 2025 Jul 14 Mon 14:15:33-0600
>>>
>>> These are updated with every IERS Bulletin C leapsecond announcement and
>>> data update, made available in the next tzdata release.
>>
>> I read up on leap secs and TAI yesterday, and it seems Linux is not doing
>> as lot by itself (i.e., the kernel).  Also, leap secs are pretty static,
>> especially since 2017. We had no leap sec since that time anymore, so we're
>> on a 37 sec shift for ~8 years.
>>
>> We need some way to handle that without extra packages.  Ideally this is
>> between the Cygwin DLL and the OS with no extra layer between them.
>> Unfortunately I didn't find a Windows API to ask the OS for the current
>> leap secs offset.
>>
>> What we could do is to define CLOCK_TAI as CLOCK_REALTIME + 37 in the DLL
>> for the time being, and the DLL could check if a file "/etc/leapsecs"
>> exists and read it to compensate for new leap secs.  We can add such a
>> file to the distro when a new leap sec has been defined.
> 
> It may be better to just use the standard approach and standard file name which 
> is /etc/leap-seconds.list, often symlinked from /etc/ntp/ which may itself be 
> symlinked from /var/lib/ntp/.
> 
> Fedora chrony (RH default ntp implementation alternative) relies on Fedora 
> tzdata to provide it, as the IERS upstream is included in the sources, and it is 
> installed in /usr/share/zoneinfo, with the tzdata processed format leapseconds.
> 
>      https://src.fedoraproject.org/rpms/chrony/blob/main/f/chrony.spec
>      https://src.fedoraproject.org/rpms/tzdata/blob/main/f/tzdata.spec
>      https://src.fedoraproject.org/rpms/ntpsec/blob/main/f/ntpsec.spec
> 
> I could do the same in Cygwin tzdata, installing symlink(s) as above, leading 
> back to /etc/leap-seconds.list, via any intermediates deemed necessary.
> 
> The dev tzdata sources are available from:
> 
>      https://github.com/eggert/tz
> 
>      https://github.com/eggert/tz/blob/main/leap-seconds.list
> 
> and the last non-comment line contains the current TAI offset and effective date 
> as the NTP time stamp (NTP epoch is 1900-01-01 00:00:00Z so that offset from 
> UNIX epoch can be added to convert):
> 
>      $ grep '^[^#]' /etc/leap-seconds.list | tail -1
>      3692217600      37      # 1 Jan 2017
>      $ date -u -d'1900-01-01 00:00:00+0000' +%s
>      -2208988800
>      $ date -u -d'1900-01-01 00:00:00+0000 + 3692217600 seconds'
>      2017 Jan 01 Sun 00:00:00
>> So, yeah, we can just add CLOCK_TAI and we add that functionality to
>> the Cygwin DLL for the 3.7 release cycle. Shouldn't be too much work.
>>
>> So, Sebastian, just go ahead defining CLOCK_TAI.  A __BSD_VISIBLE
>> guard seems like a good idea.  Maybe adding a `|| _GNU_VISIBLE' for
>> readability, even if that's redundant...
> I run [Meinberg] ntpd/ntpq not w32tm, but another system shows:
> 
>  > w32tm /query /status /verbose
> Leap Indicator: 0(no warning)
> Stratum: 2 (secondary reference - syncd by (S)NTP)
> Precision: -23 (119.209ns per tick)
> Root Delay: 0.0561072s
> Root Dispersion: 7.7939052s
> ReferenceId: 0xD8C5E4E6 (source IP:  216.197.228.230)
> Last Successful Sync Time: 2025-07-15 7:31:24 AM
> Source: 0.ca.pool.ntp.org
> Poll Interval: 15 (32768s)
> 
> Phase Offset: -0.0022481s
> ClockRate: 0.0156250s
> State Machine: 2 (Sync)
> Time Source Flags: 0 (None)
> Server Role: 576 (Reliable Time Service)
> Last Sync Error: 2 (The computer did not resync because only stale time data was 
> available.)
> 
> Time since Last Good Sync Time: 19676.7457267s
> 
>  > w32tm /leapseconds /getstatus /verbose
> 
> [Leap Seconds]
> Enabled: 1 (Local)
> Number of Leap Seconds (after June 2018): 0 (Local)
> Leap Seconds List (Local):
> 
> https://learn.microsoft.com/en-us/windows-server/networking/windows-time- 
> service/windows-time-service-tools-and-settings
> 
> https://techcommunity.microsoft.com/blog/networkingblog/top-10-networking- 
> features-in-windows-server-2019-10-accurate-network-time/339739
> 
> https://techcommunity.microsoft.com/blog/networkingblog/leap-seconds-for-the-it- 
> pro-what-you-need-to-know/339811

Also:

https://techcommunity.microsoft.com/blog/networkingblog/leap-seconds-for-the-appdev-what-you-should-know/339813
  
Corinna Vinschen July 16, 2025, 9:18 a.m. UTC | #7
On Jul 15 15:01, brian.inglis--- via Newlib wrote:
> On 2025-07-15 02:43, Corinna Vinschen via Newlib wrote:
> > On Jul 14 14:38, Brian Inglis via Newlib wrote:
> > > On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
> > > > On Jul 11 06:35, Sebastian Huber wrote:
> > > > > FreeBSD also provides this clock identifier, maybe it should be
> > > > > #if __BSD_VISIBLE
> > > > > #define CLOCK_TAI		(11)
> > > > > #endif
> > > > > ?
> > > 
> > > > Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.
> > > 
> > > > IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
> > > > return the same value, because the leap second is set to 0 at kernel
> > > > startup.  Maybe that's enough...
> > > 
> > > If you are running an NTP server you just have to ask for the system variable:
> > > [...]
> > What we could do is to define CLOCK_TAI as CLOCK_REALTIME + 37 in the DLL
> > for the time being, and the DLL could check if a file "/etc/leapsecs"
> > exists and read it to compensate for new leap secs.  We can add such a
> > file to the distro when a new leap sec has been defined.
> 
> It may be better to just use the standard approach and standard file name
> which is /etc/leap-seconds.list, often symlinked from /etc/ntp/ which may
> itself be symlinked from /var/lib/ntp/.

Actually, yesterday I hacked some POC code in my local Cygwin sandbox
using the file /usr/share/zoneinfo/leapseconds from tzdata.  If the file
isn't present, the DLL uses the current leap secs offset of 37 secs.
Seems to work nicely.

So I'm looking forward to Sebastian adding the CLOCK_TAI macro to time.h.


Corinna
  
Corinna Vinschen July 16, 2025, 10:38 a.m. UTC | #8
On Jul 16 11:18, Corinna Vinschen via Newlib wrote:
> On Jul 15 15:01, brian.inglis--- via Newlib wrote:
> > On 2025-07-15 02:43, Corinna Vinschen via Newlib wrote:
> > > On Jul 14 14:38, Brian Inglis via Newlib wrote:
> > > > On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
> > > > > On Jul 11 06:35, Sebastian Huber wrote:
> > > > > > FreeBSD also provides this clock identifier, maybe it should be
> > > > > > #if __BSD_VISIBLE
> > > > > > #define CLOCK_TAI		(11)
> > > > > > #endif
> > > > > > ?
> > > > 
> > > > > Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.
> > > > 
> > > > > IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
> > > > > return the same value, because the leap second is set to 0 at kernel
> > > > > startup.  Maybe that's enough...
> > > > 
> > > > If you are running an NTP server you just have to ask for the system variable:
> > > > [...]
> > > What we could do is to define CLOCK_TAI as CLOCK_REALTIME + 37 in the DLL
> > > for the time being, and the DLL could check if a file "/etc/leapsecs"
> > > exists and read it to compensate for new leap secs.  We can add such a
> > > file to the distro when a new leap sec has been defined.
> > 
> > It may be better to just use the standard approach and standard file name
> > which is /etc/leap-seconds.list, often symlinked from /etc/ntp/ which may
> > itself be symlinked from /var/lib/ntp/.
> 
> Actually, yesterday I hacked some POC code in my local Cygwin sandbox
> using the file /usr/share/zoneinfo/leapseconds from tzdata.  If the file
> isn't present, the DLL uses the current leap secs offset of 37 secs.
> Seems to work nicely.
> 
> So I'm looking forward to Sebastian adding the CLOCK_TAI macro to time.h.

I pushed Sebastians patch at his request.

Btw, Brian, the Fedora tzdata package contains not only the file
/usr/share/zoneinfo/leapseconds, but additionally the original file
/usr/share/zoneinfo/leap-seconds.list.

Can you please add it to your Cygwin tzdata package as well?


Thanks,
Corinna
  
Brian Inglis July 16, 2025, 5:39 p.m. UTC | #9
On 2025-07-16 04:38, Corinna Vinschen wrote:
> On Jul 16 11:18, Corinna Vinschen via Newlib wrote:
>> On Jul 15 15:01, brian.inglis--- via Newlib wrote:
>>> On 2025-07-15 02:43, Corinna Vinschen via Newlib wrote:
>>>> On Jul 14 14:38, Brian Inglis via Newlib wrote:
>>>>> On 2025-07-14 09:45, Corinna Vinschen via Newlib wrote:
>>>>>> On Jul 11 06:35, Sebastian Huber wrote:
>>>>>>> FreeBSD also provides this clock identifier, maybe it should be
>>>>>>> #if __BSD_VISIBLE
>>>>>>> #define CLOCK_TAI		(11)
>>>>>>> #endif
>>>>>>> ?
>>>>>
>>>>>> Probably, but I seriously wonder how to implement CLOCK_TAI on Cygwin.
>>>>>
>>>>>> IIUC, if you don't do anything special, the CLOCK_REALTIME and CLOCK_TAI
>>>>>> return the same value, because the leap second is set to 0 at kernel
>>>>>> startup.  Maybe that's enough...
>>>>>
>>>>> If you are running an NTP server you just have to ask for the system variable:
>>>>> [...]
>>>> What we could do is to define CLOCK_TAI as CLOCK_REALTIME + 37 in the DLL
>>>> for the time being, and the DLL could check if a file "/etc/leapsecs"
>>>> exists and read it to compensate for new leap secs.  We can add such a
>>>> file to the distro when a new leap sec has been defined.
>>>
>>> It may be better to just use the standard approach and standard file name
>>> which is /etc/leap-seconds.list, often symlinked from /etc/ntp/ which may
>>> itself be symlinked from /var/lib/ntp/.
>>
>> Actually, yesterday I hacked some POC code in my local Cygwin sandbox
>> using the file /usr/share/zoneinfo/leapseconds from tzdata.  If the file
>> isn't present, the DLL uses the current leap secs offset of 37 secs.
>> Seems to work nicely.
>>
>> So I'm looking forward to Sebastian adding the CLOCK_TAI macro to time.h.

Please do not base anything on tzdata leapseconds file, as that is really an 
internal implementation detail for zic in tzdata, generated by a tzdb awk script 
leapseconds.awk from leap-seconds.list.
That is a hack Paul came up with to avoid using leap-seconds.list directly for 
whatever reason, and may change or disappear if anything changes in zic, tzdata, 
or leap seconds, or his or another maintainer's approach.
Downstream compatibility is rarely an upstream concern; it is the responsibility 
of the downstream packagers to their users; why there has been a compatibility 
fork; and the instability could be why there have only been a few experimental 
tzdist servers, intended to distribute online updates of any releases globally.
To my mind, it should have been implemented internally within zic! ;^>

> I pushed Sebastians patch at his request.
> 
> Btw, Brian, the Fedora tzdata package contains not only the file
> /usr/share/zoneinfo/leapseconds, but additionally the original file
> /usr/share/zoneinfo/leap-seconds.list.
> 
> Can you please add it to your Cygwin tzdata package as well?

They are both included in upstream tzdata.
I can push out a release that packages the leap-seconds.list and makes it 
available from /etc/leap-seconds.list -> /etc/ntp/ -> /var/lib/ntp/?

Those paths were derived from a combo of BSD, Debian, Fedora, OpenSuSE setups 
and scripts, as the upstream leap-seconds.list are FTP and local symlinks to 
original files leap-seconds.########## where ########## is the NTP timestamp of 
the file creation per the NTP crypto file spec:

$ TZ=UTC ls -Gg leap-seconds.??????????
-r--r--r-- 1  9854 Jan 11  2012 leap-seconds.3535228800
-r--r--r-- 1 10381 Jan  5  2015 leap-seconds.3629404800
-r--r--r-- 1  4928 Apr  3  2015 leap-seconds.3637008000
-r--r--r-- 1  4928 Jul  7  2015 leap-seconds.3645216000
-r--r--r-- 1 10378 Jul 11  2015 leap-seconds.3645639840
-r--r--r-- 1  4927 Sep 16  2015 leap-seconds.3651350400
-r--r--r-- 1  4928 Jan 11  2016 leap-seconds.3661459200
-r--r--r-- 1  4928 Jan 13  2016 leap-seconds.3661632000
-r--r--r-- 1  4920 Jul  6  2016 leap-seconds.3676752000
-r--r--r-- 1 10404 Jul  8  2016 leap-seconds.3676924800
-r--r--r-- 1  4921 Jan  9  2017 leap-seconds.3692908800
-r--r--r-- 1  4925 Jan 19  2017 leap-seconds.3693772800
-r--r--r-- 1  8795 Apr 18  2017 leap-seconds.3701462400
-r--r--r-- 1  4921 Jul  7  2017 leap-seconds.3708374400
-r--r--r-- 1  4923 Jan  9  2018 leap-seconds.3724483581
-r--r--r-- 1  8788 Jan 10  2018 leap-seconds.3724531200
-r--r--r-- 1  4921 Jul  5  2018 leap-seconds.3739787886
-r--r--r-- 1  8788 Oct 12  2018 leap-seconds.3748291200
-r--r--r-- 1  4925 Jan  7  2019 leap-seconds.3755859566
-r--r--r-- 1  8789 Jan 28  2019 leap-seconds.3757622400
-r--r--r-- 1  4953 Jan  7  2020 leap-seconds.3787382231
-r--r--r-- 1  4949 Jul  7  2020 leap-seconds.3803144275
-r--r--r-- 1  4949 Jul  5  2021 leap-seconds.3834432000
-r--r--r-- 1  4953 Jan  5  2022 leap-seconds.3850377469
-r--r--r-- 1  4949 Jul  5  2022 leap-seconds.3865995417
-r--r--r-- 1  4949 Jul  4  2023 leap-seconds.3897417600
-r--r--r-- 1  5069 Jan  8  2024 leap-seconds.3913697179
-r--r--r-- 1  5064 Jul  4  2024 leap-seconds.3929093563
-r--r--r-- 1  5069 Jan  7  2025 leap-seconds.3945196800
-r--r--r-- 2  5065 Jul  7 00:00 leap-seconds.3960835200

Updated files are created within the first two work weeks of each half year, and 
expire on the 28th of the last month of the half year in which the next Bulletin 
C announcement should be made, and the next update created, normally, allowing 
for nearly six months slack in making the next announcement, and dealing with 
any issues in the released files, which in the past have included update and 
expiry dates, timestamps, and hashes.

Originally leap-seconds files were distributed by NTP servers to their clients, 
but lack of servers and bandwidth with a surfeit of clients and requests 
eliminated that approach, later FTP servers stopped being provided by NTP 
servers, and servers supporting FTP generally were dropped, reducing the 
upstreams to just IERS, NIST, and USNO (when the .mil firewalls allow!)
  
Corinna Vinschen July 16, 2025, 7:04 p.m. UTC | #10
On Jul 16 11:39, Brian Inglis wrote:
> On 2025-07-16 04:38, Corinna Vinschen wrote:
> > Btw, Brian, the Fedora tzdata package contains not only the file
> > /usr/share/zoneinfo/leapseconds, but additionally the original file
> > /usr/share/zoneinfo/leap-seconds.list.
> > 
> > Can you please add it to your Cygwin tzdata package as well?
> 
> They are both included in upstream tzdata.
> I can push out a release that packages the leap-seconds.list and makes it
> available from /etc/leap-seconds.list -> /etc/ntp/ -> /var/lib/ntp/?

No. Please just add it to your next tzdata package at the same
spot it's on Fedora, i.e. /usr/share/zoneinfo/leap-seconds.list.


Thanks,
Corinna
  
Brian Inglis July 16, 2025, 8:52 p.m. UTC | #11
On 2025-07-16 13:04, Corinna Vinschen wrote:
> On Jul 16 11:39, Brian Inglis wrote:
>> On 2025-07-16 04:38, Corinna Vinschen wrote:
>>> Btw, Brian, the Fedora tzdata package contains not only the file
>>> /usr/share/zoneinfo/leapseconds, but additionally the original file
>>> /usr/share/zoneinfo/leap-seconds.list.
>>>
>>> Can you please add it to your Cygwin tzdata package as well?
>>
>> They are both included in upstream tzdata.
>> I can push out a release that packages the leap-seconds.list and makes it
>> available from /etc/leap-seconds.list -> /etc/ntp/ -> /var/lib/ntp/?
> 
> No. Please just add it to your next tzdata package at the same
> spot it's on Fedora, i.e. /usr/share/zoneinfo/leap-seconds.list.

That is a extremely non-standard location for *any* access to leap-seconds.list 
from any system, and like anything else in tzdata, it could change or be 
dropped: it should at least be symlinked from /etc/?

Or some declaration needs to be specified somewhere:

RH chrony requires leapseclist:

	https://chrony-project.org/doc/4.7/chrony.conf.html#leapseclist

	leapseclist /usr/share/zoneinfo/leap-seconds.list

NTF ntpd defaults to and ntpsec requires leapfile:

	#leapfile   /etc/leap-seconds.list
  

Patch

diff --git a/newlib/libc/include/time.h b/newlib/libc/include/time.h
index a2df4f7fd..58939a378 100644
--- a/newlib/libc/include/time.h
+++ b/newlib/libc/include/time.h
@@ -291,6 +291,8 @@  extern "C" {
 
 #define CLOCK_BOOTTIME_ALARM	(9)
 
+#define CLOCK_TAI		(11)
+
 #endif
 
 #if defined(_POSIX_CPUTIME)