printf("File: %s\n", filename); printf(" Last Status Change (ctime): %s", ctime(&sb.st_ctime)); // ctime 包含换行符 printf(" Last Modification (mtime): %s", ctime(&sb.st_mtime)); printf(" Last Access (atime): %s", ctime(&sb.st_atime)); printf("\n"); }
// 辅助函数:创建一个测试文件 voidcreate_test_file(constchar *filename) { FILE*f=fopen(filename, "w"); if (!f) { perror("fopen"); exit(EXIT_FAILURE); } fprintf(f, "This is a test file for utimensat/futimens example.\n"); fclose(f); printf("Created test file: %s\n\n", filename); }
int main() { constchar*test_file="utimensat_test_file.txt"; constchar*test_symlink="utimensat_test_symlink.txt"; structtimespecnew_times[2]; time_tfixed_time_sec; structtmtm_tmp;
printf("--- Demonstrating utimensat and futimens ---\n");
printf("\nCalling utimensat() on symlink WITH AT_SYMLINK_NOFOLLOW...\n"); printf(" This will modify the SYMLINK's timestamps (if filesystem supports it).\n"); if (utimensat(AT_FDCWD, test_symlink, new_times, AT_SYMLINK_NOFOLLOW) ==-1) { if (errno==EOPNOTSUPP) { printf("utimensat with AT_SYMLINK_NOFOLLOW failed: %s\n", strerror(errno)); printf(" This is expected on many filesystems (e.g., ext4).\n"); } else { perror("utimensat (nofollow symlink)"); } } else { printf("utimensat() succeeded (modified symlink itself).\n"); print_file_times(test_symlink); }
// 8. 清理 printf("\n6. --- Cleaning up ---\n"); if (unlink(test_file) ==0) { printf("Deleted test file '%s'.\n", test_file); } else { perror("unlink test_file"); } if (unlink(test_symlink) ==0) { printf("Deleted symlink '%s'.\n", test_symlink); } else { perror("unlink test_symlink"); }
printf("\n--- Summary ---\n"); printf("1. futimens(fd, times[2]): Sets atime/mtime for a file via its file descriptor.\n"); printf("2. utimensat(dirfd, pathname, times[2], flags): Sets atime/mtime via pathname, with more options.\n"); printf("3. Both use struct timespec, providing nanosecond precision.\n"); printf("4. Special timespec values:\n"); printf(" - tv_nsec = UTIME_NOW: Set timestamp to current time.\n"); printf(" - tv_nsec = UTIME_OMIT: Leave timestamp unchanged.\n"); printf("5. utimensat flags:\n"); printf(" - 0 (default): Follow symlinks.\n"); printf(" - AT_SYMLINK_NOFOLLOW: Modify symlink itself (filesystem support varies).\n"); printf(" - dirfd allows relative path resolution (like openat).\n"); printf("6. These are the modern, preferred functions for changing file timestamps.\n");
---Demonstratingutimensatandfutimens--- Created test file:utimensat_test_file.txt
Created symlink:utimensat_test_symlink.txt->utimensat_test_file.txt
1. Initial timestamps: File:utimensat_test_file.txt Last Status Change (ctime):FriOct2711:00:002023 Last Modification (mtime):FriOct2711:00:002023 Last Access (atime):FriOct2711:00:002023
File:utimensat_test_symlink.txt Last Status Change (ctime):FriOct2711:00:002023 Last Modification (mtime):FriOct2711:00:002023 Last Access (atime):FriOct2711:00:002023
2.Preparingfixedtime... 3.---Usingfutimens()--- Settingtimestampsusingfutimens()... futimens()succeeded. Timestamps after futimens: File:utimensat_test_file.txt Last Status Change (ctime):FriOct2711:00:002023 Last Modification (mtime):FriOct2710:00:002023 Last Access (atime):FriOct2710:00:002023
4.---Usingutimensat()withrelativepath--- SettingatimetoNOWandmtimetoOMITusingutimensat(AT_FDCWD,...)... utimensat()succeeded. Timestampsafterutimensat(atimeupdated,mtime unchanged): File:utimensat_test_file.txt Last Status Change (ctime):FriOct2711:00:022023 Last Modification (mtime):FriOct2710:00:002023 Last Access (atime):FriOct2711:00:022023
5.---Usingutimensat()withsymlinks--- Callingutimensat()onsymlinkWITHOUTAT_SYMLINK_NOFOLLOW... ThiswillmodifytheTARGETfile'stimestamps. utimensat()succeeded(followedsymlink). Target file timestamps after utimensat (followed symlink): File:utimensat_test_file.txt Last Status Change (ctime):FriOct2711:00:022023 Last Modification (mtime):FriOct2712:00:002023 Last Access (atime):FriOct2711:00:002023 Symlink file timestamps (should be unchanged or linked): File:utimensat_test_symlink.txt ...(sameastarget)...
Callingutimensat()onsymlinkWITHAT_SYMLINK_NOFOLLOW... ThiswillmodifytheSYMLINK'stimestamps(iffilesystemsupportsit). utimensat with AT_SYMLINK_NOFOLLOW failed:Operationnotsupported Thisisexpectedonmanyfilesystems(e.g.,ext4).