概述
一个文件的访问与修改时间可以通过以下几个函数进行修改。同时, futimens
和utimensat
函数可以指定纳米级精度的时间戳。
#include <sys/stat.h>
int futimens(int fd, const struct timespec times[2]);
int utimensat(int fd, const char *path, const struct timespec times[2], int flag);
两个函数返回值: 若成功,返回 0;若出错,返回 -1。
结构体timespec
:
struct timespec{
time_t tv_sec; // seconds 秒
long tv_nsec; // nanoseconds 纳秒
}
以上两个函数的times
数组参数的第一个元素包含访问时间,第二个元素包含修改时间。这两个时间值均是日历时间,这是自特定时间(1970年1月1日 00:00:00)以来所经过的秒数。
时间戳可以按下列四种方式之一进行指定。
- 如果
times
参数是一个空指针,则访问时间和修改时间两者都设置为当前时间。 - 如果
times
参数指向两个timespec结构的数组,任一数组元素的tv_nsec
字段的值为UTIME_NOW
, 相应的时间戳就设置为当前时间,忽略相应的tv_sec
字段。 - 如果
times
参数指向两个timespec
结构的数组, 任一数组元素的tv_nsec
字段的值为UTIME_OMIT
, 相应的时间戳保持不变,忽略相应的tv_sec
字段。 - 如果
times
参数指向两个timespec
结构的数组,且tv_nsec
字段的值既不是UTIME_NOW
也不是UTIME_OMIT
, 在这种情况下,相应的时间戳设置为相应的tv_sec
和tv_nsec
字段的值。
执行这些函数所要求的的优先权取决于times
参数的值。
- 如果
times
是一个空指针,或者任一tv_nsec
字段设为UTIME_NOW
,则进程的有效用户ID必须是该文件的所有者ID;进程对文件必须具有写权限,或者进程是一个超级用户进程。 - 如果
times
是非空指针, 并且任一tv_nsec
字段的值既不是UTIME_NOW
也不是UTIME_OMIT
,则进程的有效用户ID必须等于该文件的所有者ID,或者进程必须是一个超级用户进程,对文件只具有写权限是不够的。 - 如果
times
是非空指针,并且两个tv_nsec
字段的值都为UTIME_OMIT
,就不执行任何的权限检查。
futimens
函数通过打开文件来更改它的时间, utimensat
函数通过提供文件名的方式来更改文件的时间。pathname
参数相对于fd
参数进行计算,fd
要么是打开目录的文件描述符,要么设置为特殊值AT_FDCWD
。如果pathname
指定了绝对路径,那么fd
参数被忽略。flag
参数进一步修改默认行为,如果设置为AT_SYMLINK_NOFOLLOW
标志,则符号链接本身的时间就会被修改。默认行为是跟随符号链接,并把文件的时间改成符号链接的时间。
测试样例如下:
void test1(){
int fd;
if((fd = open("fu_file", O_RDWR|O_TRUNC)) < 0)
err_ret("fu_file: open error.");
if(futimens(fd, NULL) < 0)
err_ret("fu_file: futimens error.");
printf("futimens changes.n");
close(fd);
}
void test2(){
if(utimensat(AT_FDCWD, "ut_file", NULL, AT_SYMLINK_NOFOLLOW) < 0)
err_ret("ut_file: utimensat error.");
printf("utimensat changes.n");
}
第三个要介绍的函数即是utimes
。
#include <sys/time.h>
int utimes(const char *pathname, const struct timeval times[2]);
函数返回值:若成功,返回0;若出错,返回 -1。
timeval
结构体:
struct timeval{
time_t tv_sec; // seconds 秒
long tv_usec; // microseconds 微秒
}
此函数不能对状态更改时间st_ctime
指定一个值,因为调用utimes
函数时,此字段会自动更新。
#include "../../include/apue.h"
#include <fcntl.h>
int main(int argc, char *argv[])
{
int i, fd;
struct stat statbuf;
struct timespec times[2];
for(i = 1; i < argc; i++){
if(stat(argv[i], &statbuf) < 0){
err_ret("%s: stat error.", argv[i]);
continue;
}
if((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0){
err_ret("%s: open error.",argv[i]);
continue;
}
times[0] = statbuf.st_atim;
times[1] = statbuf.st_mtim;
if(futimens(fd, times) < 0)
err_ret("%s: futimens error.", argv[i]);
close(fd);
}
return 0;
}
结果图如下:
如上图所见,最后修改时间和最后访问时间是未改变的,但是状态更改时间则更改为程序运行时的时间。
最后
以上就是无奈小丸子为你收集整理的文件和目录之函数futimens、utimensat和utimes的全部内容,希望文章能够帮你解决文件和目录之函数futimens、utimensat和utimes所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复