futimens, utimensat, and utimes Functions

一系列用于改变文件访问时间( access )和修改时间( modification )的系统调用

futimens, utimensat - change file timestamps with nanosecond precision

futimens, utimensat 提供纳秒尺寸,通过使用timespec结构体。

#include <fcntl.h> /* Definition of AT_* constants */
#include <sys/stat.h>

int futimens(int fd, const struct timespec times[2]);
int utimensat(int dirfd, const char *pathname,
                     const struct timespec times[2], int flags);
//Return: 0 if OK, -1 on error

结构体:timespec

struct timespec {
               time_t tv_sec;        /* seconds */
               long   tv_nsec;       /* nanoseconds */
};

futimens

times[0]存放的access time,times[1]存放modification time.这两个时间是日历时间(calendar time)。

timestamps(时间戳)可以用下面4种方法来指定:
1. times是NULL指针。这样timestamps被设置为当前时间。
2. timestimespec结构体数组。如果tv_nsec field为特殊值UTIME_NOW,相应的timestamp被设定为当前时间。相应的tv_secfield被忽略。
3. timestimespec结构体数组。如果tv_nsec field为特殊值UTIME_OMIT,相应的timestamp不改变。相应的tv_secfield被忽略。
4. timestimespec结构体数组。如果tv_nsec fieldUTIME_OMITUTIME_NOW以外的值,timestamp相应地被设置为tv_sectv_nsec field的值。

需要执行这些系统调用的权限由times 参数决定:

  • If times is a null pointer or if either tv_nsec field is set to UTIME_NOW, either the effective user ID of the process must equal the owner ID of the file, the process must have write permission for the file, or the process must be a superuser process.
  • If times is a non-null pointer and either tv_nsec field has a value other than UTIME_NOW or UTIME_OMIT, the effective user ID of the process must equal the owner ID of the file, or the process must be a superuser process. Merely having write permission for the file is not adequate(仅仅有文件的write权限是不够的).
  • If times is a non-null pointer and both tv_nsec fields are set to UTIME_OMIT, no permissions checks are performed.

With futimens, you need to open the file to change its times.

utimensat

The utimensat function provides a way to change a file’s times using the file’s name. The pathname argument is evaluated relative to the dirfd argument, which is either a file descriptor of an open directory or the special value AT_FDCWDto force evaluation relative to the current directory of the calling process. If pathname specifies an absolute pathname(绝对路径), then the dirfd argument is ignored.

The flag argument to utimensat can be used to further modify the default behavior. If the AT_SYMLINK_NOFOLLOW flag is set, then the times of the symbolic link itself are changed (if the pathname refers to a symbolic link). The default behavior is to follow a symbolic link and modify the times of the file to which the link refers.

Both futimens and utimensat are included in POSIX.1.(如上介绍到两种系统调用都是包含在POSIX1规范中的)

utime, utimes - change file last access and modification times

#include <sys/types.h>
#include <utime.h>
int utime(const char *filename, const struct utimbuf *times);

#include <sys/time.h>
int utimes(const char *filename, const struct timeval times[2]);
//Return 0 if OK, -1 on error

需要注意的是这两个函数修改的是秒和毫秒(ms)不是纳秒

struct timeval {
    time_t tv_sec;   /* seconds */
    long   tv_usec;  /* microseconds */
};

我们发现,changed-status timest_ctim—inode最后修改的时间,我们是无法指定其值的,该值会在调用utime的时候自动更新。

在一些Unix版本的命令中,touch使用了这些系统调用之一。此外tarcpio等标准archive存档程序中也使用了这些系统调用来设置文件时间。

Example

使用openO_TRUNC截断文件长度到0,但是不改变他们的access time或者modification time.为了达到这一目的,我们先用stat获取时间,然后截断文件,最后使用futimens来重置(reset)时间

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
    int fd;
    struct stat timebuf;
    struct timespec times[2];
/*先确定命令行参数合法性*/
    if(argc != 2)
    {
        fprintf(stderr, "usage: a.out <file pathname>\n");
        exit(-1);
    }
/*获取文件截断前数据*/
    if(stat(argv[1], &timebuf) != 0)
    {
        fprintf(stderr, "stat error!\n");
        exit(-1);
    }
 /*用open截短文件*/
    if((fd = open(argv[1], O_TRUNC)) < 0)
    {
        fprintf(stderr, "open error: %s\n", strerror(errno));
        exit(-1);
    }
    times[0] = timebuf.st_atim;
    times[1] = timebuf.st_mtim;
/*设置文件时间与截断前一致*/
    if(futimens(fd, times) != 0)
    {
        fprintf(stderr, "futimens error: %s\n", strerror(errno));
        exit(-1);
    }

    close(fd);

    return 0;
}

验证:

$ls -l file
$./a.out file
$ls -l     `check time`
$ls -lu    `check last-access time`
$ls -lc    `check changed-status time`

你会发现last-modificationlast-access时间都没有改变,但是changed-status times已经被更改到程序运行的时间

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值