int main() { struct stat stat_info, lstat_info, fstat_info; int fd; const char *target_file = "target_file.txt"; const char *symlink_name = "my_symlink";
// 创建一个目标文件 (如果不存在) FILE *f = fopen(target_file, "w"); if (f) { fprintf(f, "This is the target file.\n"); fclose(f); printf("Created target file: %s\n", target_file); } else { perror("Failed to create target file"); // 即使创建失败,也可能文件已存在,继续尝试后续步骤 }
// 创建符号链接 (如果不存在) if (symlink(target_file, symlink_name) == -1) { if (errno != EEXIST) { // EEXIST 表示链接已存在,可以接受 perror("Failed to create symbolic link"); // 清理可能已创建的目标文件 unlink(target_file); exit(EXIT_FAILURE); } else { printf("Symbolic link '%s' already exists.\n", symlink_name); } } else { printf("Created symbolic link '%s' -> '%s'\n", symlink_name, target_file); }
// --- 使用 stat --- printf("\n--- Using stat('%s', ...) ---\n", symlink_name); if (stat(symlink_name, &stat_info) == -1) { perror("stat failed"); } else { printf(" Inode: %ld (This is the INODE of the TARGET file)\n", (long)stat_info.st_ino); printf(" Size: %ld bytes\n", (long)stat_info.st_size); if (S_ISLNK(stat_info.st_mode)) { printf(" Type: Symbolic Link (This should NOT happen with stat)\n"); } else { printf(" Type: Not a Symbolic Link (stat followed the link)\n"); } }
// --- 使用 lstat --- printf("\n--- Using lstat('%s', ...) ---\n", symlink_name); if (lstat(symlink_name, &lstat_info) == -1) { perror("lstat failed"); } else { printf(" Inode: %ld (This is the INODE of the SYMBOLIC LINK itself)\n", (long)lstat_info.st_ino); printf(" Size: %ld bytes (Size of the link's PATHNAME string)\n", (long)lstat_info.st_size); if (S_ISLNK(lstat_info.st_mode)) { printf(" Type: Symbolic Link (lstat did NOT follow the link)\n"); } else { printf(" Type: Not a Symbolic Link (Unexpected)\n"); } }
// --- 使用 fstat --- printf("\n--- Using fstat(fd_of_symlink, ...) ---\n"); // 打开符号链接本身 (需要 O_PATH 或 O_RDONLY, 且不跟随链接的行为取决于系统和标志,但 fstat 总是作用于已打开的 fd) // 更准确的做法是打开目标文件来演示 fstat fd = open(target_file, O_RDONLY); // 打开目标文件 if (fd == -1) { perror("Failed to open target file for fstat"); // 清理 unlink(symlink_name); unlink(target_file); exit(EXIT_FAILURE); }
if (fstat(fd, &fstat_info) == -1) { perror("fstat failed"); } else { printf(" Inode: %ld (Inode of the file associated with fd %d)\n", (long)fstat_info.st_ino, fd); printf(" Size: %ld bytes\n", (long)fstat_info.st_size); if (S_ISLNK(fstat_info.st_mode)) { printf(" Type: Symbolic Link (Associated file is a symlink)\n"); } else { printf(" Type: Not a Symbolic Link (Associated file is regular/dir/etc)\n"); } } close(fd); // 关闭 fstat 使用的文件描述符