diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -45,9 +45,6 @@ def StructTimeSpec : NamedType<"struct timespec">; def StructTimeSpecPtr : PtrType; -def StructTimeVal : NamedType<"struct timeval">; -def StructTimeValPtr : PtrType; - def ExecArgvT : NamedType<"__exec_argv_t">; def ExecEnvpT : NamedType<"__exec_envp_t">; @@ -733,7 +730,7 @@ UidT, GidT, StructTimeSpec, - StructTimeVal, + StructTimevalType, BlkSizeT, BlkCntT, OffTType, @@ -1077,7 +1074,7 @@ HeaderSpec Time = HeaderSpec< "time.h", [], // Macros - [ClockIdT, StructTimeSpec, StructTimeVal], // Types + [ClockIdT, StructTimeSpec, StructTimevalType], // Types [], // Enumerations [ FunctionSpec< @@ -1088,7 +1085,7 @@ FunctionSpec< "gettimeofday", RetValSpec, - [ArgSpec, ArgSpec] + [ArgSpec, ArgSpec] >, FunctionSpec< "nanosleep", diff --git a/libc/src/time/gettimeofday.cpp b/libc/src/time/gettimeofday.cpp --- a/libc/src/time/gettimeofday.cpp +++ b/libc/src/time/gettimeofday.cpp @@ -10,7 +10,6 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" -#include "src/time/clock_gettime.h" #include #include // For syscall numbers. @@ -23,9 +22,15 @@ return 0; clockid_t clockid = CLOCK_REALTIME; struct timespec tp; - long ret_val = __llvm_libc::clock_gettime(clockid, &tp); - if (ret_val < 0) + long ret_val = + __llvm_libc::syscall_impl(SYS_clock_gettime, static_cast(clockid), + reinterpret_cast(&tp)); + // A negative return value indicates an error with the magnitude of the + // value being the error code. + if (ret_val < 0) { + errno = -ret_val; return -1; + } tv->tv_sec = tp.tv_sec; tv->tv_usec = tp.tv_nsec / 1000; return 0; diff --git a/libc/test/src/time/gettimeofday_test.cpp b/libc/test/src/time/gettimeofday_test.cpp --- a/libc/test/src/time/gettimeofday_test.cpp +++ b/libc/test/src/time/gettimeofday_test.cpp @@ -20,19 +20,23 @@ using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds; void *tz = nullptr; struct timeval tv; - int ret = __llvm_libc::gettimeofday(&tv, tz); - ASSERT_EQ(ret, 0); - // Sleep for 200 microsceconds. - struct timespec tim = {0, 200 * 1000}; - struct timespec tim2 = {0, 0}; - ret = __llvm_libc::nanosleep(&tim, &tim2); + int sleep_times[2] = {200, 1000}; + for (int i = 0; i < 2; i++) { + int ret = __llvm_libc::gettimeofday(&tv, tz); + ASSERT_EQ(ret, 0); - // Call gettimeofday again and verify that it is more 100 microscecods and - // less than 300 microseconds, - struct timeval tv1; - ret = __llvm_libc::gettimeofday(&tv1, tz); - ASSERT_EQ(ret, 0); - ASSERT_GT(tv1.tv_usec - tv.tv_usec, 100); - ASSERT_LT(tv1.tv_usec - tv.tv_usec, 300); + int sleep_time = -sleep_times[i]; + // Sleep for {sleep_time} microsceconds. + struct timespec tim = {0, sleep_time * 1000}; + struct timespec tim2 = {0, 0}; + ret = __llvm_libc::nanosleep(&tim, &tim2); + + // Call gettimeofday again and verify that it is more {sleep_time} + // microscecods. + struct timeval tv1; + ret = __llvm_libc::gettimeofday(&tv1, tz); + ASSERT_EQ(ret, 0); + ASSERT_GE(tv1.tv_usec - tv.tv_usec, sleep_time); + } }