为什么 `.` 和 `..` 在 Mac 上的 `/` 中有不同的索引节点号?
Why does `.` and `..` have different inode numbers inside `/` on a Mac?
我正在尝试实现自己的 pwd
命令。要找到整个路径,我需要遍历 inode
树直到到达根,判断我已经到达根的方法是检查为 [= 存储的相等 inode
数字16=] 和 ..
.
但在我的 Mac 看来情况并非如此,至少如果您查看下面的 table。
dirent | stat | link to
-----------+------------+--------
34078072 | 34078072 | self
31103058 | 31103058 | parent
31103058 | 31103058 | self
31103020 | 31103020 | parent
31103020 | 31103020 | self
613497 | 613497 | parent
613497 | 613497 | self
603204 | 603204 | parent
603204 | 603204 | self
157433 | 157433 | parent
157433 | 157433 | self
2 | 2 | parent
2 | 2 | self // This is root aka /
1 | 2 | parent // There is something above it?
这是使用下面的代码生成的。 stat
结构似乎运行良好,但 dirent
在涉及 /
时具有不同的值。为什么会这样? dirent
和 stat
不应该具有相同的 inode 编号值吗?为什么 Mac 不同?
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
void inodes();
int main()
{
printf(" dirent | stat | link to\n");
printf("-----------+------------+--------\n");
inodes();
return 0;
}
void inodes()
{
DIR* directory = opendir(".");
struct dirent* entry = NULL;
struct stat status;
ino_t self = -1;
ino_t parent = -1;
while ((entry = readdir(directory))) {
stat(entry->d_name, &status);
if (strcmp(entry->d_name, ".") == 0) {
self = status.st_ino;
printf("%10.llu | %10.llu | self\n", entry->d_ino, self);
}
if (strcmp(entry->d_name, "..") == 0) {
parent = status.st_ino;
printf("%10.llu | %10.llu | parent\n", entry->d_ino, parent);
}
}
if (self != parent) {
if (chdir("..") != -1) {
inodes();
}
}
}
在 Macintosh HFS+ 文件系统上,每个文件和文件夹都有一个唯一的
"file ID"。该文件系统在 Apple 的
"Technical Note TN1150 – HFS Plus Volume Format".
特别是,根文件夹 始终 具有文件 ID 2 和父文件夹
ID 1。在 TN1150 中,这些记录为
enum {
kHFSRootParentID = 1,
kHFSRootFolderID = 2,
...
}
kHFSRootParentID
Parent ID of the root folder.
kHFSRootFolderID
Folder ID of the root folder.
HFS+ 文件系统上的 inode 准确反映
文件 ID。这可以解释为什么 readdir()
报告索引节点
2
为“.”根文件夹的条目,inode 1
根文件夹的“..”条目。 (但我对这一事实没有明确的参考。可以尝试在以下位置找到源代码
http://www.opensource.apple.com:)
另一方面,根文件夹中的“..”始终是 link
根文件夹本身。因此,当
stat(entry->d_name, &status);
为 ".." 条目执行,根文件夹上的 stat()
已完成,
所以这再次给出了 inode 2
。
我正在尝试实现自己的 pwd
命令。要找到整个路径,我需要遍历 inode
树直到到达根,判断我已经到达根的方法是检查为 [= 存储的相等 inode
数字16=] 和 ..
.
但在我的 Mac 看来情况并非如此,至少如果您查看下面的 table。
dirent | stat | link to
-----------+------------+--------
34078072 | 34078072 | self
31103058 | 31103058 | parent
31103058 | 31103058 | self
31103020 | 31103020 | parent
31103020 | 31103020 | self
613497 | 613497 | parent
613497 | 613497 | self
603204 | 603204 | parent
603204 | 603204 | self
157433 | 157433 | parent
157433 | 157433 | self
2 | 2 | parent
2 | 2 | self // This is root aka /
1 | 2 | parent // There is something above it?
这是使用下面的代码生成的。 stat
结构似乎运行良好,但 dirent
在涉及 /
时具有不同的值。为什么会这样? dirent
和 stat
不应该具有相同的 inode 编号值吗?为什么 Mac 不同?
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
void inodes();
int main()
{
printf(" dirent | stat | link to\n");
printf("-----------+------------+--------\n");
inodes();
return 0;
}
void inodes()
{
DIR* directory = opendir(".");
struct dirent* entry = NULL;
struct stat status;
ino_t self = -1;
ino_t parent = -1;
while ((entry = readdir(directory))) {
stat(entry->d_name, &status);
if (strcmp(entry->d_name, ".") == 0) {
self = status.st_ino;
printf("%10.llu | %10.llu | self\n", entry->d_ino, self);
}
if (strcmp(entry->d_name, "..") == 0) {
parent = status.st_ino;
printf("%10.llu | %10.llu | parent\n", entry->d_ino, parent);
}
}
if (self != parent) {
if (chdir("..") != -1) {
inodes();
}
}
}
在 Macintosh HFS+ 文件系统上,每个文件和文件夹都有一个唯一的 "file ID"。该文件系统在 Apple 的 "Technical Note TN1150 – HFS Plus Volume Format".
特别是,根文件夹 始终 具有文件 ID 2 和父文件夹 ID 1。在 TN1150 中,这些记录为
enum {
kHFSRootParentID = 1,
kHFSRootFolderID = 2,
...
}
kHFSRootParentID
Parent ID of the root folder.
kHFSRootFolderID
Folder ID of the root folder.
HFS+ 文件系统上的 inode 准确反映
文件 ID。这可以解释为什么 readdir()
报告索引节点
2
为“.”根文件夹的条目,inode 1
根文件夹的“..”条目。 (但我对这一事实没有明确的参考。可以尝试在以下位置找到源代码
http://www.opensource.apple.com:)
另一方面,根文件夹中的“..”始终是 link 根文件夹本身。因此,当
stat(entry->d_name, &status);
为 ".." 条目执行,根文件夹上的 stat()
已完成,
所以这再次给出了 inode 2
。