Compare commits
5 Commits
a9da58421f
...
e705810af3
Author | SHA1 | Date | |
---|---|---|---|
e705810af3 | |||
e2b5c1bfdd | |||
324fb42ee2 | |||
688a640a16 | |||
baf97840e9 |
@ -1,4 +1,4 @@
|
|||||||
APPS := init sh uname uptime hello ps ls args cat stat su session
|
APPS := init sh uname uptime hello ps ls args cat stat su session date
|
||||||
|
|
||||||
APPS_DIR := $(LUNA_ROOT)/apps
|
APPS_DIR := $(LUNA_ROOT)/apps
|
||||||
APPS_SRC := $(APPS_DIR)/src
|
APPS_SRC := $(APPS_DIR)/src
|
||||||
|
9
apps/src/date.c
Normal file
9
apps/src/date.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
time_t date = time(NULL);
|
||||||
|
|
||||||
|
fputs(ctime(&date), stdout);
|
||||||
|
}
|
@ -1,27 +1,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <time.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
FILE* fp = fopen("/dev/uptime", "r");
|
struct timespec tp;
|
||||||
if (!fp)
|
clock_gettime(CLOCK_MONOTONIC, &tp); // On Luna, CLOCK_MONOTONIC starts at boot.
|
||||||
{
|
|
||||||
perror("fopen");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buf[BUFSIZ];
|
printf("up for %ld seconds\n", tp.tv_sec);
|
||||||
fgets(buf, sizeof(buf), fp);
|
|
||||||
|
|
||||||
if (ferror(fp))
|
|
||||||
{
|
|
||||||
perror("fgets");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
long ms_uptime = atol(buf);
|
|
||||||
|
|
||||||
printf("up for %ld seconds\n", ms_uptime / 1000);
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
}
|
@ -18,7 +18,7 @@
|
|||||||
#define SYS_execv 12
|
#define SYS_execv 12
|
||||||
#define SYS_fcntl 13
|
#define SYS_fcntl 13
|
||||||
#define SYS_mprotect 14
|
#define SYS_mprotect 14
|
||||||
#define SYS_clock 15
|
#define SYS_clock_gettime 15
|
||||||
#define SYS_mkdir 16
|
#define SYS_mkdir 16
|
||||||
#define SYS_fork 17
|
#define SYS_fork 17
|
||||||
#define SYS_waitpid 18
|
#define SYS_waitpid 18
|
||||||
@ -34,6 +34,7 @@
|
|||||||
struct stat;
|
struct stat;
|
||||||
struct pstat;
|
struct pstat;
|
||||||
struct luna_dirent;
|
struct luna_dirent;
|
||||||
|
struct timespec;
|
||||||
|
|
||||||
namespace Syscall
|
namespace Syscall
|
||||||
{
|
{
|
||||||
@ -55,7 +56,7 @@ void sys_seek(Context* context, int fd, long offset, int whence);
|
|||||||
void sys_execv(Context* context, const char* pathname, char** argv);
|
void sys_execv(Context* context, const char* pathname, char** argv);
|
||||||
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg);
|
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg);
|
||||||
void sys_mprotect(Context* context, void* address, size_t size, int prot);
|
void sys_mprotect(Context* context, void* address, size_t size, int prot);
|
||||||
void sys_clock(Context* context);
|
void sys_clock_gettime(Context* context, int clock_id, struct timespec* tp);
|
||||||
void sys_mkdir(Context* context, const char* filename, mode_t mode);
|
void sys_mkdir(Context* context, const char* filename, mode_t mode);
|
||||||
void sys_fork(Context* context);
|
void sys_fork(Context* context);
|
||||||
void sys_waitpid(Context* context, long pid, int* wstatus, int options);
|
void sys_waitpid(Context* context, long pid, int* wstatus, int options);
|
||||||
|
8
kernel/include/utils/Time.h
Normal file
8
kernel/include/utils/Time.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int make_yday(int year, int month);
|
||||||
|
|
||||||
|
uint64_t broken_down_to_unix(uint64_t year, uint64_t yday, uint64_t hour, uint64_t min, uint64_t sec);
|
||||||
|
|
||||||
|
uint64_t unix_boottime(uint8_t boottime[8]);
|
@ -17,6 +17,7 @@
|
|||||||
#include "render/TextRenderer.h"
|
#include "render/TextRenderer.h"
|
||||||
#include "std/assert.h"
|
#include "std/assert.h"
|
||||||
#include "std/string.h"
|
#include "std/string.h"
|
||||||
|
#include "utils/Time.h"
|
||||||
|
|
||||||
extern BOOTBOOT bootboot;
|
extern BOOTBOOT bootboot;
|
||||||
extern "C" char environment[4096];
|
extern "C" char environment[4096];
|
||||||
@ -36,6 +37,7 @@ void Init::disable_smp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void asm_enable_sse();
|
extern "C" void asm_enable_sse();
|
||||||
|
extern void clock_init();
|
||||||
|
|
||||||
void Init::early_init()
|
void Init::early_init()
|
||||||
{
|
{
|
||||||
@ -55,6 +57,8 @@ void Init::early_init()
|
|||||||
}
|
}
|
||||||
else if (!strstr(environment, "verbose=1")) { KernelLog::toggle_log_level(LogLevel::DEBUG); }
|
else if (!strstr(environment, "verbose=1")) { KernelLog::toggle_log_level(LogLevel::DEBUG); }
|
||||||
|
|
||||||
|
clock_init();
|
||||||
|
|
||||||
InitRD::init();
|
InitRD::init();
|
||||||
|
|
||||||
Mersenne::init();
|
Mersenne::init();
|
||||||
|
@ -26,7 +26,7 @@ void Syscall::entry(Context* context)
|
|||||||
case SYS_execv: sys_execv(context, (const char*)context->rdi, (char**)context->rsi); break;
|
case SYS_execv: sys_execv(context, (const char*)context->rdi, (char**)context->rsi); break;
|
||||||
case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break;
|
case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break;
|
||||||
case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break;
|
case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break;
|
||||||
case SYS_clock: sys_clock(context); break;
|
case SYS_clock_gettime: sys_clock_gettime(context, (int)context->rdi, (struct timespec*)context->rsi); break;
|
||||||
case SYS_mkdir: sys_mkdir(context, (const char*)context->rdi, (mode_t)context->rsi); break;
|
case SYS_mkdir: sys_mkdir(context, (const char*)context->rdi, (mode_t)context->rsi); break;
|
||||||
case SYS_fork: sys_fork(context); break;
|
case SYS_fork: sys_fork(context); break;
|
||||||
case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break;
|
case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break;
|
||||||
|
@ -1,9 +1,73 @@
|
|||||||
|
#include "bootboot.h"
|
||||||
#include "interrupts/Context.h"
|
#include "interrupts/Context.h"
|
||||||
|
#include "std/errno.h"
|
||||||
|
#include "sys/UserMemory.h"
|
||||||
|
#include "thread/PIT.h"
|
||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
|
#include "utils/Time.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
void sys_clock(Context* context)
|
static uint64_t unix_boot_time;
|
||||||
|
|
||||||
|
#define CLOCK_REALTIME 0
|
||||||
|
#define CLOCK_MONOTONIC 1
|
||||||
|
#define CLOCK_PROCTIME 2
|
||||||
|
|
||||||
|
struct timeval
|
||||||
{
|
{
|
||||||
|
time_t tv_sec;
|
||||||
|
suseconds_t tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timespec
|
||||||
|
{
|
||||||
|
time_t tv_sec;
|
||||||
|
long tv_nsec;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ms_to_timespec(long ms, struct timespec* tv)
|
||||||
|
{
|
||||||
|
tv->tv_sec = ms / 1000;
|
||||||
|
tv->tv_nsec = (ms % 1000) * 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_clock_gettime(Context* context, int clock, struct timespec* tp)
|
||||||
|
{
|
||||||
|
struct timespec* ktp = obtain_user_ref(tp);
|
||||||
|
if (!ktp)
|
||||||
|
{
|
||||||
|
context->rax = -EFAULT; // FIXME: Not sure if clock_gettime can return EFAULT.
|
||||||
|
return;
|
||||||
|
}
|
||||||
Task* current_task = Scheduler::current_task();
|
Task* current_task = Scheduler::current_task();
|
||||||
context->rax = (long)current_task->cpu_time;
|
switch (clock)
|
||||||
|
{
|
||||||
|
case CLOCK_REALTIME: {
|
||||||
|
ms_to_timespec(PIT::ms_since_boot, ktp);
|
||||||
|
ktp->tv_sec += unix_boot_time;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CLOCK_MONOTONIC: {
|
||||||
|
ms_to_timespec(PIT::ms_since_boot, ktp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CLOCK_PROCTIME: {
|
||||||
|
ms_to_timespec(current_task->cpu_time, ktp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
release_user_ref(ktp);
|
||||||
|
context->rax = -EINVAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
release_user_ref(ktp);
|
||||||
|
context->rax = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern BOOTBOOT bootboot;
|
||||||
|
|
||||||
|
void clock_init()
|
||||||
|
{
|
||||||
|
unix_boot_time = unix_boottime(bootboot.datetime);
|
||||||
|
}
|
42
kernel/src/utils/Time.cpp
Normal file
42
kernel/src/utils/Time.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#define MODULE "time"
|
||||||
|
|
||||||
|
#include "utils/Time.h"
|
||||||
|
#include "log/Log.h"
|
||||||
|
|
||||||
|
int isleap(int year)
|
||||||
|
{
|
||||||
|
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int make_yday(int year, int month)
|
||||||
|
{
|
||||||
|
static const short int upto[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||||
|
int yd;
|
||||||
|
|
||||||
|
yd = upto[month - 1];
|
||||||
|
if (month > 2 && isleap(year)) yd++;
|
||||||
|
return yd;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t broken_down_to_unix(uint64_t year, uint64_t yday, uint64_t hour, uint64_t min, uint64_t sec)
|
||||||
|
{
|
||||||
|
return sec + min * 60 + hour * 3600 + yday * 86400 + (year - 70) * 31536000 + ((year - 69) / 4) * 86400 -
|
||||||
|
((year - 1) / 100) * 86400 + ((year + 299) / 400) * 86400;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bcd_number_to_decimal(int num)
|
||||||
|
{
|
||||||
|
return ((num >> 4) * 10) + (num & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t unix_boottime(uint8_t boottime[8])
|
||||||
|
{
|
||||||
|
int year = bcd_number_to_decimal(boottime[0]) * 100 + bcd_number_to_decimal(boottime[1]);
|
||||||
|
int month = bcd_number_to_decimal(boottime[2]);
|
||||||
|
int day = bcd_number_to_decimal(boottime[3]);
|
||||||
|
int hour = bcd_number_to_decimal(boottime[4]);
|
||||||
|
int minute = bcd_number_to_decimal(boottime[5]);
|
||||||
|
int second = bcd_number_to_decimal(boottime[6]);
|
||||||
|
kinfoln("UTC boot time: %d-%d-%d %d:%d:%d", year, month, day, hour, minute, second);
|
||||||
|
return broken_down_to_unix(year - 1900, make_yday(year, month) + (day - 1), hour, minute, second);
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
#define SYS_execv 12
|
#define SYS_execv 12
|
||||||
#define SYS_fcntl 13
|
#define SYS_fcntl 13
|
||||||
#define SYS_mprotect 14
|
#define SYS_mprotect 14
|
||||||
#define SYS_clock 15
|
#define SYS_clock_gettime 15
|
||||||
#define SYS_mkdir 16
|
#define SYS_mkdir 16
|
||||||
#define SYS_fork 17
|
#define SYS_fork 17
|
||||||
#define SYS_waitpid 18
|
#define SYS_waitpid 18
|
||||||
|
@ -34,4 +34,7 @@ typedef int uid_t;
|
|||||||
/* Type representing a group ID. */
|
/* Type representing a group ID. */
|
||||||
typedef int gid_t;
|
typedef int gid_t;
|
||||||
|
|
||||||
|
/* Type representing a system clock. */
|
||||||
|
typedef int clockid_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -16,19 +16,27 @@ struct tm
|
|||||||
int tm_wday;
|
int tm_wday;
|
||||||
int tm_yday;
|
int tm_yday;
|
||||||
int tm_isdst;
|
int tm_isdst;
|
||||||
|
|
||||||
long tm_gmtoff;
|
|
||||||
const char* tm_zone;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Captures elapsed time.
|
// Captures elapsed time with microsecond precision.
|
||||||
struct timeval
|
struct timeval
|
||||||
{
|
{
|
||||||
time_t tv_sec;
|
time_t tv_sec;
|
||||||
suseconds_t tv_usec;
|
suseconds_t tv_usec;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CLOCKS_PER_SEC 1000 // Number of clock_t per second.
|
// Captures elapsed time with nanosecond precision.
|
||||||
|
struct timespec
|
||||||
|
{
|
||||||
|
time_t tv_sec;
|
||||||
|
long tv_nsec;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CLOCKS_PER_SEC 10000000 // Number of clock_t per second.
|
||||||
|
|
||||||
|
#define CLOCK_REALTIME 0
|
||||||
|
#define CLOCK_MONOTONIC 1
|
||||||
|
#define CLOCK_PROCTIME 2
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
@ -39,11 +47,36 @@ extern "C"
|
|||||||
* get the value in seconds. */
|
* get the value in seconds. */
|
||||||
clock_t clock(void);
|
clock_t clock(void);
|
||||||
|
|
||||||
/* FIXME: For now, is an alias for clock(), but in seconds. */
|
/* Returns the current UNIX time in seconds, which is also stored in tloc if it is nonnull. */
|
||||||
time_t time(time_t* tloc);
|
time_t time(time_t* tloc);
|
||||||
|
|
||||||
struct tm* localtime(const time_t* timep); // Not implemented.
|
/* Retrieves precise time from a specific system clock. */
|
||||||
struct tm* gmtime(const time_t* timep); // Not implemented.
|
int clock_gettime(clockid_t clock_id, struct timespec* tp);
|
||||||
|
|
||||||
|
/* Converts the UNIX timestamp time to broken-down time in UTC. */
|
||||||
|
struct tm* gmtime(const time_t* time);
|
||||||
|
|
||||||
|
/* Converts the UNIX timestamp time to broken-down time in UTC. Thread-safe. */
|
||||||
|
struct tm* gmtime_r(const time_t* time, struct tm* result);
|
||||||
|
|
||||||
|
/* Converts the UNIX timestamp time to broken-down time in local time. */
|
||||||
|
struct tm* localtime(const time_t* time);
|
||||||
|
|
||||||
|
/* Converts the UNIX timestamp time to broken-down time in local time. Thread-safe. */
|
||||||
|
struct tm* localtime_r(const time_t* time, struct tm* result);
|
||||||
|
|
||||||
|
/* Returns a string representation of the broken-down time in the time structure. */
|
||||||
|
char* asctime(const struct tm* time);
|
||||||
|
|
||||||
|
/* Fills buf with the string representation of the broken-down time in the time structure. Thread-safe. */
|
||||||
|
char* asctime_r(const struct tm* time, char buf[26]);
|
||||||
|
|
||||||
|
/* Returns a string representation of time. */
|
||||||
|
char* ctime(const time_t* time);
|
||||||
|
|
||||||
|
/* Fills buf with a string representation of time. Thread-safe. */
|
||||||
|
char* ctime_r(const time_t* time, char buf[26]);
|
||||||
|
|
||||||
size_t strftime(char* str, size_t max, const char* format, const struct tm* time); // Not implemented.
|
size_t strftime(char* str, size_t max, const char* format, const struct tm* time); // Not implemented.
|
||||||
char* ctime(const time_t* timep); // Not implemented.
|
char* ctime(const time_t* timep); // Not implemented.
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ extern "C" long syscall(long number, ...)
|
|||||||
va_start(ap, number);
|
va_start(ap, number);
|
||||||
switch (number)
|
switch (number)
|
||||||
{
|
{
|
||||||
case SYS_clock:
|
|
||||||
case SYS_yield:
|
case SYS_yield:
|
||||||
case SYS_fork: result = __luna_syscall0(number); break;
|
case SYS_fork: result = __luna_syscall0(number); break;
|
||||||
case SYS_exit:
|
case SYS_exit:
|
||||||
@ -26,6 +25,7 @@ extern "C" long syscall(long number, ...)
|
|||||||
case SYS_fstat:
|
case SYS_fstat:
|
||||||
case SYS_stat:
|
case SYS_stat:
|
||||||
case SYS_dup2:
|
case SYS_dup2:
|
||||||
|
case SYS_clock_gettime:
|
||||||
case SYS_setuid:
|
case SYS_setuid:
|
||||||
case SYS_setgid:
|
case SYS_setgid:
|
||||||
case SYS_pstat: {
|
case SYS_pstat: {
|
||||||
|
@ -1,42 +1,164 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include <luna.h>
|
#include <luna.h>
|
||||||
#include <luna/syscall.h>
|
#include <luna/syscall.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define SECONDS_PER_DAY 86400
|
||||||
|
|
||||||
|
static int isleap(int year)
|
||||||
|
{
|
||||||
|
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int make_yday(int year, int month)
|
||||||
|
{
|
||||||
|
static const short int upto[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||||
|
int yd;
|
||||||
|
|
||||||
|
yd = upto[month - 1];
|
||||||
|
if (month > 2 && isleap(year)) yd++;
|
||||||
|
return yd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int day_of_week(int year, int mon, int day)
|
||||||
|
{
|
||||||
|
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
|
||||||
|
year -= mon < 3;
|
||||||
|
return (year + year / 4 - year / 100 + year / 400 + t[mon - 1] + day) % 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void time_to_struct_tm(time_t time, struct tm* result)
|
||||||
|
{
|
||||||
|
result->tm_isdst = 0; // No DST/timezone support for now.
|
||||||
|
|
||||||
|
int year = 1970;
|
||||||
|
|
||||||
|
while (time > 0)
|
||||||
|
{
|
||||||
|
time_t seconds_in_year = (isleap(year) ? 366 : 365) * SECONDS_PER_DAY;
|
||||||
|
if (seconds_in_year <= time)
|
||||||
|
{
|
||||||
|
year++;
|
||||||
|
time -= seconds_in_year;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int month_days[] = {31, isleap(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
|
|
||||||
|
int month = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
time_t seconds_in_month = month_days[month] * SECONDS_PER_DAY;
|
||||||
|
if (seconds_in_month <= time)
|
||||||
|
{
|
||||||
|
month++;
|
||||||
|
time -= seconds_in_month;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int day = (int)(time / SECONDS_PER_DAY);
|
||||||
|
time %= SECONDS_PER_DAY;
|
||||||
|
|
||||||
|
assert(day < month_days[month]);
|
||||||
|
|
||||||
|
int hour = (int)(time / 3600);
|
||||||
|
time %= 3600;
|
||||||
|
|
||||||
|
int min = (int)(time / 60);
|
||||||
|
time %= 60;
|
||||||
|
|
||||||
|
result->tm_year = year - 1900;
|
||||||
|
result->tm_mon = month + 1;
|
||||||
|
result->tm_yday = make_yday(year, month + 1) + day; // FIXME: Support tm_wday.
|
||||||
|
result->tm_wday = day_of_week(year, month + 1, day + 1);
|
||||||
|
result->tm_mday = day + 1;
|
||||||
|
result->tm_hour = hour;
|
||||||
|
result->tm_min = min;
|
||||||
|
result->tm_sec = (int)time;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* wday_names[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||||
|
const char* month_names[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
clock_t clock()
|
clock_t clock()
|
||||||
{
|
{
|
||||||
return __lc_fast_syscall0(SYS_clock);
|
struct timespec tp;
|
||||||
|
clock_gettime(CLOCK_PROCTIME, &tp);
|
||||||
|
return (tp.tv_sec * CLOCKS_PER_SEC) + (tp.tv_nsec / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t time(
|
time_t time(time_t* tloc)
|
||||||
time_t* tloc) // Very big FIXME: This is not the time of day, this just returns the same as clock() but in
|
|
||||||
// seconds. This is definitely wrong, but I'm not implementing a whole time system right now.
|
|
||||||
{
|
{
|
||||||
time_t result = (time_t)(syscall(SYS_clock) / CLOCKS_PER_SEC);
|
struct timespec tp;
|
||||||
if (tloc) { *tloc = result; }
|
clock_gettime(CLOCK_REALTIME, &tp);
|
||||||
|
if (tloc) { *tloc = tp.tv_sec; }
|
||||||
|
return tp.tv_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clock_gettime(clockid_t clock_id, struct timespec* tp)
|
||||||
|
{
|
||||||
|
return (int)__lc_fast_syscall2(SYS_clock_gettime, clock_id, tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm* localtime(const time_t* time)
|
||||||
|
{
|
||||||
|
static struct tm result;
|
||||||
|
return localtime_r(time, &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm* gmtime(const time_t* time)
|
||||||
|
{
|
||||||
|
static struct tm result;
|
||||||
|
return gmtime_r(time, &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm* localtime_r(const time_t* time, struct tm* result)
|
||||||
|
{
|
||||||
|
return gmtime_r(time, result); // FIXME: Implement timezones.
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm* gmtime_r(const time_t* time, struct tm* result)
|
||||||
|
{
|
||||||
|
time_to_struct_tm(*time, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tm* localtime(const time_t*)
|
char* asctime_r(const struct tm* time, char buf[26])
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("localtime");
|
snprintf(buf, 26, "%s %s %d %d:%d:%d %d\n", wday_names[time->tm_wday], month_names[time->tm_mon - 1],
|
||||||
|
time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec, time->tm_year + 1900);
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tm* gmtime(const time_t*)
|
char* asctime(const struct tm* time)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("gmtime");
|
static char buf[26];
|
||||||
|
return asctime_r(time, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ctime_r(const time_t* time, char buf[26])
|
||||||
|
{
|
||||||
|
struct tm stm;
|
||||||
|
return asctime_r(localtime_r(time, &stm), buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ctime(const time_t* time)
|
||||||
|
{
|
||||||
|
return asctime(localtime(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t strftime(char*, size_t, const char*, const struct tm*)
|
size_t strftime(char*, size_t, const char*, const struct tm*)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED("strftime");
|
NOT_IMPLEMENTED("strftime");
|
||||||
}
|
}
|
||||||
|
|
||||||
char* ctime(const time_t*)
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED("ctime");
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user