如何使用 settimeofday(2)?

Jos*_*son 1 c linux posix glibc

我在这里做错了什么?我希望settimeofday()更改系统时间,而不是 return EINVAL。

$ uname -a
Linux io 4.3.5-300.fc23.x86_64 #1 SMP Mon Feb 1 03:18:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
$ cat settimeofday.c 
#include <sys/time.h>
#include <stdio.h>

int main()
{
    struct timeval tv = {0, 0};
    if (settimeofday(&tv, 0) == -1)
        perror("settimeofday");
}
$ gcc settimeofday.c 
$ sudo ./a.out 
settimeofday: Invalid argument
Run Code Online (Sandbox Code Playgroud)

该错误来自运行 Fedora 23 的 Thinkpad T450。相同的代码在 OS X 上运行良好。

编辑

澄清一下,该命令正在以 root 身份执行:

# whoami
root
# sudo ./a.out 
settimeofday: Invalid argument
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,如果我以普通用户身份运行程序,我会得到 EPERM 而不是 EINVAL:

$ ./a.out 
settimeofday: Operation not permitted
Run Code Online (Sandbox Code Playgroud)

Jos*_*son 5

Commit e1d7ba于 2015 年年中引入 Linux 内核,并限制了 tv_sec 字段的值。该限制受系统正常运行时间的影响——有关详细信息,请参阅提交消息和相关的 LKML 讨论。

这就是导致settimeofday调用返回的EINVAL原因,并解释了为什么代码在 OS X 和较旧的 Linux 机器上运行。