commit 5ae1defa290e118c161e476b5220ee4934ba85db
parent 4c18ab2794cd222bbbf8067b2e15e1ab7e9a1c45
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date: Fri, 17 Apr 2026 10:35:56 +0200
libc/time: Make _gmtoff() optional
The function gmtoff() requires a big array that is useless in many
systems what lack the tiime zone concept. For that reason it makes
more sense to move the call to this function to _tzset() and for
simplicity and just in case some platform only requires _gmtoff()
but no _tzset() the code for _gmtoff() is generated and compiled
always but only included in the list of object to insert to the
library when it is required.
Diffstat:
10 files changed, 57 insertions(+), 45 deletions(-)
diff --git a/src/libc/arch/posix/_tzone.c b/src/libc/arch/posix/_tzone.c
@@ -228,7 +228,6 @@ void
_tzset(void)
{
char *tz = getenv("TZ");
- int i;
_tzname[1] = _tzname[0] = "UTC";
_tzstdoff = _tzdstoff = (time_t) -1;
@@ -236,13 +235,19 @@ _tzset(void)
_tzjulian = 0;
if (!tz)
- return;
+ goto adjust;
next(tz);
if (!std())
- return;
+ goto adjust;
if (!dst())
- return;
+ goto adjust;
if (!rule())
- return;
+ goto adjust;
+
+adjust:
+ if (_tzstdoff == -1)
+ _tzstdoff = _gmtoff(_tzname[0]);
+ if (_tzdstoff == -1)
+ _tzdstoff = _gmtoff(_tzname[1]);
}
diff --git a/src/libc/libc.h b/src/libc/libc.h
@@ -41,6 +41,7 @@ extern int _tzjulian;
extern int _daysmon[12];
+long _gmtoff(char *);
void _tzset(void);
int _daysyear(int);
int _newyear(int);
diff --git a/src/libc/objs/amd64-freebsd.mk b/src/libc/objs/amd64-freebsd.mk
@@ -24,3 +24,4 @@ OBJS =\
arch/posix/time.$O\
arch/posix/tmpfile.$O\
string/strlen.$O\
+ time/tz.$O\
diff --git a/src/libc/objs/amd64-linux.mk b/src/libc/objs/amd64-linux.mk
@@ -47,3 +47,4 @@ OBJS =\
arch/posix/time.$O\
arch/posix/tmpfile.$O\
string/strlen.$O\
+ time/tz.$O\
diff --git a/src/libc/objs/amd64-netbsd.mk b/src/libc/objs/amd64-netbsd.mk
@@ -40,3 +40,4 @@ OBJS =\
arch/posix/time.$O\
arch/posix/tmpfile.$O\
string/strlen.$O\
+ time/tz.$O\
diff --git a/src/libc/objs/amd64-openbsd.mk b/src/libc/objs/amd64-openbsd.mk
@@ -44,3 +44,4 @@ OBJS =\
arch/posix/time.$O\
arch/posix/tmpfile.$O\
string/strlen.$O\
+ time/tz.$O\
diff --git a/src/libc/time/Makefile b/src/libc/time/Makefile
@@ -13,13 +13,12 @@ OBJS =\
localtime.$O\
mktime.$O\
strftime.$O\
+ tz.$O\
all: $(OBJS)
tz.c: timezone.lst
- awk -f gentz.awk timezone.lst > $@
-
-localtime.$O: tz.c
+ ./gentz timezone.lst > $@
tz.$O: tz.c
$(CC) $(PROJ_CFLAGS) -c -o $@ tz.c
diff --git a/src/libc/time/gentz b/src/libc/time/gentz
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+cat <<'EOF'
+#include <string.h>
+#include <time.h>
+
+#include "../libc.h"
+
+struct tzone {
+ char *name;
+ long gmtoff;
+};
+
+static struct tzone tzones[];
+
+long
+_gmtoff(char *tz)
+{
+ struct tzone *t;
+
+ for (t = tzones; t->name; t++) {
+ if (!strcmp(t->name, tz))
+ return t->gmtoff;
+ }
+ return 0;
+}
+
+EOF
+
+awk '
+BEGIN {print "static struct tzone tzones[] = {" }
+{
+ split($2,a,":")
+ min = a[1] * 60
+ min = min + a[2]
+ sec = min * 60
+ printf "\t{\"%s\", %d},\n", $1, sec
+}
+END { print "\t{0,\t0}\n};\n" }' "$@"
diff --git a/src/libc/time/gentz.awk b/src/libc/time/gentz.awk
@@ -1,9 +0,0 @@
-BEGIN { print "struct tzone tzones[] = {" }
-{
- split($2,a,":")
- min = a[1] * 60
- min = min + a[2]
- sec = min * 60
- printf "\t{\"%s\", %d},\n", $1, sec
-}
-END { print "\t{0,\t0}\n};\n" }
diff --git a/src/libc/time/localtime.c b/src/libc/time/localtime.c
@@ -4,28 +4,6 @@
#include "../libc.h"
#undef localtime
-struct tzone {
- char *name;
- int gmtoff;
-};
-
-#include "tz.c"
-
-static time_t
-gmtoff(char *tz)
-{
- struct tzone *t;
-
- if (!strcmp(tz, "UTC"))
- return 0;
-
- for (t = tzones; t->name; t++) {
- if (!strcmp(t->name, tz))
- return t->gmtoff;
- }
- return 0;
-}
-
struct tm *
localtime(const time_t *timep)
{
@@ -39,13 +17,8 @@ localtime(const time_t *timep)
tm = gmtime(&t);
yday = tm->tm_yday;
- if (first) {
+ if (first)
_tzset();
- if (_tzstdoff == -1)
- _tzstdoff = gmtoff(_tzname[0]);
- if (_tzdstoff == -1)
- _tzdstoff = gmtoff(_tzname[1]);
- }
first = 0;
off = _tzstdoff;