一个进程就可以完成
chdir("/to/some/where");
当来自另一个 shell 时
mv /to/some/where /now/different/path/
第一个过程
print getcwd();
#prints /now/different/path/
getcwd
是如何实现的? (在最低级别,例如在内核级别、 inode ...)。
我知道常见的(基于 inode 的)文件系统是如何工作的,例如what 包含目录(条目的名称和相应的 inode 编号)。
编辑
可能这个问题太模糊了 - 试图完善它。一种可能的情况(据 o 所知)
- 内核知道给定进程(及其线程)的
CWD
的 inode - 例如 inode 数1000
- 读取 inode(获取需要读取的 block )
- 读取相应的 block (例如打开目录)
- 读取目录条目(条目名称和 inode 编号)
- 获取
..
父目录(例如900
)的inode 编号和.
(当前目录)的inode 编号 - 读取get所在的父目录的内容
- 上一个目录的
名称
(inode1000
) - 父目录的inode号
- 继续
5.
- 直到到达根 inode。
也就是说,getcwd
用于
/some/very/very/very/deep/directory/level
需要更多的原始 IO 操作(需要读取更多的目录条目)作为简短的
/tmp
整个getcwd
是通过两次读取完成的?
这是正确的吗?还是以完全不同的方式完成?
最佳答案
首先,你问错地方了。这个问题更多是关于操作系统的,所以unix.stackexchange是更好的地方。
无论如何,对于某些古老的 UNIX 实现(例如 BSD 2.8)或类似的,您提出的解决方案是是正确的。该路径名解析可以按照您的描述完成。
但是,出现了很多问题——其中很少有:
- 如您所说 - 路径名解析太复杂(是的,对于更深的目录需要更多的 IO)
- 依赖于只有一个ROOT目录存在的前提。这在 BSD 4.2 中是不正确的,在 BSD 4.2 中引入了
per process
根目录 - 允许chroot
系统调用 - 允许将根设置为任何目录而不显示进程的真实路径。 (最酷的 FreeBSD 功能之一是 jail - 取决于此)(同样古老的 linux 只有一个根 - 仅在 0.96c 中引入了 VFS - 虚拟文件系统层) - 和许可问题——例如当
#shell1
$ mkdir -p /tmp/some
$ cd /tmp/some
第二壳
$ su
# mkdir -p /tmp/my
# chmod 700 /tmp/my
# mv /tmp/some /tmp/my/
/tmp/my
目录对于第一个进程不可读。所以,它无法确定路径,那么它应该如何处理这些文件呢?所以,再次在 shell1 中:
$ pwd
/tmp/some #the original
$ echo $CWD
/tmp/some
$ /bin/pwd
pwd: .: Permission denied
但是,你仍然可以做例子
$ touch bob #works
例如该系统允许您在“当前”目录中工作,而不会让您知道您在哪里。 (在这两种情况下,例如在 chroot 和第二种情况下);)
这意味着每个进程都在其表中存储当前工作目录:
- 设备编号(例如 hdd1 或 hdd2)
- 设备上的 inode 号
和
- 内核维护另一个全局表,(在 Linux 中称为 dentry(目录条目)),- 内核为每个进程维护“inode”->“路径”映射,每个打开的文件描述符,以及 indode 缓存(在由内核本身维护的 linux 中,BSD:
vnod
驱动程序的工作)等。
例如当某个进程请求 inode X 的路径名时,内核搜索 dentry
表,如果找到条目 - 立即返回,如果没有 - 调用 lookup
进程,什么执行路径名解析。
例如,当重命名发生时,内核会搜索 dentry
表,如果找到条目并根据需要更改它。
以上所有内容都极度简化,如您所见,以上所有内容都高度操作系统相关,共同基础由 POSIX 定义 - 但发生在后面(例如实现)——你真的需要阅读内核和/或谷歌的来源:
- Linux 目录
- Linux vfs
- freebsd vnode
- 路径名解析
等等。
Ps:对于吹毛求疵的人,:) - 正如我所说 - 一切都过于简单化,所以如果你想要更正并添加更多细节 - 编辑答案 - 我将其转换为“社区维基答案”。
关于c - getcwd 在内核(库)中是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29340806/