如何使用 settimeofday(2)?

how to use settimeofday(2)?

我在这里做错了什么?我希望 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

错误来自 Thinkpad T450 运行ning Fedora 23。相同的代码 运行 在 OS X 上没问题。

编辑

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

# whoami
root
# sudo ./a.out 
settimeofday: Invalid argument

正如预期的那样,如果我 运行 作为普通用户使用该程序,我得到的是 EPERM 而不是 EINVAL:

$ ./a.out 
settimeofday: Operation not permitted

如 settimeofday() 的联机帮助页所示。

If either tv or tz is NULL, the corresponding structure is not set or returned.

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

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