Compare commits

..

3 Commits

Author SHA1 Message Date
553b893a9c time Utility for working with time/dates 2025-10-16 14:15:55 +02:00
7445689010 ulib Time utilities, expose time() syscall 2025-10-16 14:15:27 +02:00
702f0ddf87 Add time() syscall 2025-10-16 14:15:05 +02:00
16 changed files with 179 additions and 13 deletions

View File

@ -11,6 +11,7 @@
#include "proc.h" #include "proc.h"
#include "fs.h" #include "fs.h"
#include "dev.h" #include "dev.h"
#include "time.h"
int32_t SYSCALL1(sys_debugprint, string) { int32_t SYSCALL1(sys_debugprint, string) {
char *p = (char *)string; char *p = (char *)string;
@ -52,4 +53,5 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = {
[SYS_DEV_LISTSIZE] = &sys_dev_listsize, [SYS_DEV_LISTSIZE] = &sys_dev_listsize,
[SYS_DEV_STAT] = &sys_dev_stat, [SYS_DEV_STAT] = &sys_dev_stat,
[SYS_DEV_CMD] = &sys_dev_cmd, [SYS_DEV_CMD] = &sys_dev_cmd,
[SYS_TIME] = &sys_time,
}; };

13
kernel/syscall/time.c Normal file
View File

@ -0,0 +1,13 @@
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
#include "time.h"
#include "sysdefs/time.h"
#include "time/time.h"
#include "errors.h"
int32_t SYSCALL1(sys_time, timestruct1) {
Time *time = (Time *)timestruct1;
time_get(time);
return E_OK;
}

9
kernel/syscall/time.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef SYSCALL_TIME_H_
#define SYSCALL_TIME_H_
#include <stdint.h>
#include <stddef.h>
int32_t SYSCALL1(sys_time, timestruct1);
#endif // SYSCALL_TIME_H_

View File

@ -3,17 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include "sysdefs/time.h"
typedef struct {
uint32_t second;
uint32_t minute;
uint32_t hour;
uint32_t day;
uint32_t month;
uint32_t year;
} Time;
typedef uint64_t timeunix_t;
void time_get(Time *time); void time_get(Time *time);
timeunix_t time_tounix(Time *time); timeunix_t time_tounix(Time *time);

View File

@ -34,6 +34,7 @@
#define SYS_DEV_LISTSIZE 34 #define SYS_DEV_LISTSIZE 34
#define SYS_DEV_STAT 35 #define SYS_DEV_STAT 35
#define SYS_DEV_CMD 36 #define SYS_DEV_CMD 36
#define SYS_TIME 38
#endif // SHARE_HDRS_SYSCALL_H_ #endif // SHARE_HDRS_SYSCALL_H_

15
share/sysdefs/time.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef SHARE_SYSDEFS_TIME_H_
#define SHARE_SYSDEFS_TIME_H_
typedef struct {
uint32_t second;
uint32_t minute;
uint32_t hour;
uint32_t day;
uint32_t month;
uint32_t year;
} Time;
typedef uint64_t timeunix_t;
#endif // SHARE_SYSDEFS_TIME_H_

View File

@ -16,6 +16,7 @@ SRCFILES := $(call GRABSRC, \
ubsan \ ubsan \
umalloc \ umalloc \
fs \ fs \
time \
) )
CFLAGS += -isystem $(ROOT)/share -isystem $(ROOT)/ulib -isystem $(ROOT)/std/include \ CFLAGS += -isystem $(ROOT)/share -isystem $(ROOT)/ulib -isystem $(ROOT)/std/include \

View File

@ -138,3 +138,7 @@ int32_t dev_stat(DevStat *devstatbuf, size_t idx) {
int32_t dev_cmd(Dev_t *dev, uint64_t cmd, void *buf, size_t len, void *extra) { int32_t dev_cmd(Dev_t *dev, uint64_t cmd, void *buf, size_t len, void *extra) {
return syscall(SYS_DEV_CMD, (uint64_t)dev, (uint64_t)cmd, (uint64_t)buf, (uint64_t)len, (uint64_t)extra, 0); return syscall(SYS_DEV_CMD, (uint64_t)dev, (uint64_t)cmd, (uint64_t)buf, (uint64_t)len, (uint64_t)extra, 0);
} }
int32_t time(Time *time) {
return syscall(SYS_TIME, (uint64_t)time, 0, 0, 0, 0, 0);
}

View File

@ -7,6 +7,7 @@
#include <sysdefs/dev.h> #include <sysdefs/dev.h>
#include <sysdefs/proc.h> #include <sysdefs/proc.h>
#include <sysdefs/fs.h> #include <sysdefs/fs.h>
#include <sysdefs/time.h>
void debugprint(const char *string); void debugprint(const char *string);
int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out); int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out);
@ -41,5 +42,6 @@ int32_t dev_gethandle(Dev_t *dev, char *name);
int32_t dev_listsize(void); int32_t dev_listsize(void);
int32_t dev_stat(DevStat *devstatbuf, size_t idx); int32_t dev_stat(DevStat *devstatbuf, size_t idx);
int32_t dev_cmd(Dev_t *dev, uint64_t cmd, void *buf, size_t len, void *extra); int32_t dev_cmd(Dev_t *dev, uint64_t cmd, void *buf, size_t len, void *extra);
int32_t time(Time *time);
#endif // ULIB_SYSTEM_SYSTEM_H_ #endif // ULIB_SYSTEM_SYSTEM_H_

31
ulib/time/time.c Normal file
View File

@ -0,0 +1,31 @@
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <sysdefs/time.h>
bool time_isleap(uint32_t y) {
return ((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0));
}
const uint16_t days_before_month[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
timeunix_t time_tounix(Time *time) {
uint64_t days = 0;
for (uint32_t y = 1970; y < time->year; y++) {
days += time_isleap(y) ? 366 : 365;
}
days += days_before_month[time->month - 1];
if (time->month > 2 && time_isleap(time->year)) {
days += 1;
}
days += time->day - 1;
uint64_t secs = days * 86400;
secs += time->hour * 3600;
secs += time->minute * 60;
secs += time->second;
return secs;
}

8
ulib/time/time.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef ULIB_TIME_TIME_H_
#define ULIB_TIME_TIME_H_
#include <sysdefs/time.h>
timeunix_t time_tounix(Time *time);
#endif // ULIB_TIME_TIME_H_

View File

@ -11,12 +11,13 @@
#include <syscall/syscall.h> #include <syscall/syscall.h>
#include <system/system.h> #include <system/system.h>
#include <util/util.h> #include <util/util.h>
#include <umalloc/umalloc.h>
#include <fs/path.h>
#include <time/time.h>
#include <uprintf.h> #include <uprintf.h>
#include <linklist.h> #include <linklist.h>
#include <log.h> #include <log.h>
#include <assert.h> #include <assert.h>
#include <umalloc/umalloc.h>
#include <fs/path.h>
#include <dlinklist.h> #include <dlinklist.h>
#include <errors.h> #include <errors.h>
@ -25,6 +26,7 @@
#include <sysdefs/mman.h> #include <sysdefs/mman.h>
#include <sysdefs/proc.h> #include <sysdefs/proc.h>
#include <sysdefs/sched.h> #include <sysdefs/sched.h>
#include <sysdefs/time.h>
#include <sysdefs/syscall.h> #include <sysdefs/syscall.h>
#endif // ULIB_ULIB_H_ #endif // ULIB_ULIB_H_

2
user/time/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.o
time

24
user/time/Makefile Normal file
View File

@ -0,0 +1,24 @@
include $(ROOT)/mk/grabsrc.mk
include ../Makefile.inc
.PHONY: all clean
TARGET := time
LDFLAGS += -L$(ROOT)/ulib -l:libulib.a
SRCFILES := $(call GRABSRC, .)
CFILES := $(call GET_CFILES, $(SRCFILES))
OBJ := $(call GET_OBJ, $(SRCFILES))
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
all: $(TARGET)
$(TARGET): $(OBJ)
$(LD) $^ $(LDFLAGS) -o $@
echo $$(realpath $(TARGET)) >> $(FILES)
clean:
rm -f $(OBJ) $(TARGET)

24
user/time/main.c Normal file
View File

@ -0,0 +1,24 @@
#include <stdint.h>
#include <stddef.h>
#include <ulib.h>
#define CMDS(X) \
X(now)
void main(void) {
if (argslen() == 0) {
return;
}
char *cmd = args()[0];
#define X(name) if (string_strcmp(cmd, #name) == 0) { \
extern void tm_ ## name(void); \
tm_ ## name(); \
return; \
}
CMDS(X)
#undef X
uprintf("time: unknown command %s\n", cmd);
}

38
user/time/now.c Normal file
View File

@ -0,0 +1,38 @@
#include <stdint.h>
#include <stddef.h>
#include <ulib.h>
struct {
char *format;
} TM_NOW_CONFIG = {0};
static Arg ARGS[] = {
ARG("-fmt", ARG_STRING, &TM_NOW_CONFIG.format),
ARG_END(),
};
void tm_now(void) {
int32_t ret;
if ((ret = parse_args(args()+1, argslen()-1, ARGS)) < 0) {
uprintf("time: could not parse args: %d\n", ret);
return;
}
Time tmbuf;
time(&tmbuf);
if (TM_NOW_CONFIG.format == NULL) {
uprintf("%02u/%02u/%02u %02u:%02u:%02u\n",
tmbuf.day, tmbuf.month, tmbuf.year,
tmbuf.hour, tmbuf.minute, tmbuf.second
);
return;
}
if (string_strcmp(TM_NOW_CONFIG.format, "unix") == 0) {
timeunix_t unix = time_tounix(&tmbuf);
uprintf("%lu\n", unix);
} else {
uprintf("time: unknown format %s\n", TM_NOW_CONFIG.format);
}
}