Browse Source

feat(gblibc): add gettimeofday()

greatbridf 2 năm trước cách đây
mục cha
commit
5eee6fd14b

+ 1 - 0
gblibc/CMakeLists.txt

@@ -17,6 +17,7 @@ add_library(gblibc STATIC
     src/internal.c
     src/alloca.c
     src/stat.c
+    src/time.c
 )
 
 add_library(crt0 OBJECT

+ 11 - 1
gblibc/include/bits/alltypes.h

@@ -12,7 +12,17 @@ typedef size_t blkcnt_t;
 
 struct timespec {
     time_t tv_sec;
-    long tv_nsec;
+    size_t tv_nsec;
+};
+
+struct timeval {
+    time_t tv_sec;
+    size_t tv_usec;
+};
+
+struct timezone {
+    int tz_minuteswest;
+    int tz_dsttime;
 };
 
 #ifdef __cplusplus

+ 16 - 0
gblibc/include/sys/time.h

@@ -0,0 +1,16 @@
+#ifndef __GBLIBC_SYS_TIME_H_
+#define __GBLIBC_SYS_TIME_H_
+
+#include <bits/alltypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int gettimeofday(struct timeval* tv, struct timezone* tz);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 1 - 0
gblibc/private-include/syscall.h

@@ -23,6 +23,7 @@
 #define SYS_getdents (78)
 #define SYS_getcwd (79)
 #define SYS_chdir (80)
+#define SYS_gettimeofday (96)
 #define SYS_setpgid (109)
 #define SYS_getppid (110)
 #define SYS_setsid (112)

+ 20 - 0
gblibc/src/time.c

@@ -0,0 +1,20 @@
+#include <errno.h>
+#include <sys/time.h>
+#include <syscall.h>
+
+int gettimeofday(struct timeval* tv, struct timezone* tz)
+{
+    if (tz) {
+        errno = -EINVAL;
+        return -1;
+    }
+
+    int ret = syscall2(SYS_gettimeofday, (uint32_t)tv, 0);
+
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+
+    return ret;
+}

+ 5 - 0
include/kernel/hw/timer.h

@@ -6,6 +6,11 @@
 extern "C" {
 #endif
 
+struct user_timeval {
+    time_t tv_sec;
+    size_t tv_usec;
+};
+
 void init_pit(void);
 
 void inc_tick(void);

+ 21 - 0
src/kernel/syscall.cpp

@@ -3,6 +3,7 @@
 #include <assert.h>
 #include <bits/ioctl.h>
 #include <errno.h>
+#include <kernel/hw/timer.h>
 #include <kernel/interrupt.h>
 #include <kernel/log.hpp>
 #include <kernel/mem.h>
@@ -19,6 +20,7 @@
 #include <types/lock.hpp>
 #include <types/status.h>
 #include <types/string.hpp>
+#include <types/types.h>
 
 #define SYSCALL_HANDLERS_SIZE (128)
 syscall_handler syscall_handlers[SYSCALL_HANDLERS_SIZE];
@@ -511,6 +513,24 @@ int _syscall_fstat(interrupt_stack* data)
     return __stat(file->ptr.ind, buf);
 }
 
+int _syscall_gettimeofday(interrupt_stack* data)
+{
+    auto* tv = (struct user_timeval*)data->s_regs.edi;
+    auto* tz = (void*)data->s_regs.esi;
+    // TODO: return time of the day, not time from this boot
+
+    if (unlikely(tz))
+        return -EINVAL;
+
+    if (likely(tv)) {
+        // TODO: use copy_to_user
+        tv->tv_sec = current_ticks() / 100;
+        tv->tv_usec = current_ticks() * 10 * 1000;
+    }
+
+    return 0;
+}
+
 extern "C" void syscall_entry(interrupt_stack* data)
 {
     int syscall_no = data->s_regs.eax;
@@ -549,6 +569,7 @@ void init_syscall(void)
     syscall_handlers[78] = _syscall_getdents;
     syscall_handlers[79] = _syscall_getcwd;
     syscall_handlers[80] = _syscall_chdir;
+    syscall_handlers[96] = _syscall_gettimeofday;
     syscall_handlers[109] = _syscall_setpgid;
     syscall_handlers[110] = _syscall_getppid;
     syscall_handlers[112] = _syscall_setsid;