c - getcwd 在内核(库)中是如何实现的?

标签 c directory kernel pwd

一个进程就可以完成

chdir("/to/some/where");

当来自另一个 shell 时

mv /to/some/where /now/different/path/

第一个过程

print getcwd(); 
#prints /now/different/path/

getcwd 是如何实现的? (在最低级别,例如在内核级别、 inode ...)。

我知道常见的(基于 inode 的)文件系统是如何工作的,例如what 包含目录(条目的名称和相应的 inode 编号)。

编辑

可能这个问题太模糊了 - 试图完善它。一种可能的情况(据 o 所知)

  1. 内核知道给定进程(及其线程)的 CWD 的 inode - 例如 inode 数 1000
  2. 读取 inode(获取需要读取的 block )
  3. 读取相应的 block (例如打开目录)
  4. 读取目录条目(条目名称和 inode 编号)
  5. 获取.. 父目录(例如900)的inode 编号和.(当前目录)的inode 编号
  6. 读取get所在的父目录的内容
  • 上一个目录的名称(inode 1000)
  • 父目录的inode号
  1. 继续 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/

相关文章:

c - C编程中的段错误

c++ - 数组段错误

PHP:包含和需要文件时抛出错误

python - 文件夹名称带有\n

linux - 如何停止 init_module : linux kernel

将数据从 struct net_device_stats 复制到用户空间

c - 在 Ubuntu 的虚拟机上学习 Linux 内核编程?

c - 读写共享内存

html - 您可以设置本地文档根目录吗?或者在哪里?

c - 如何访问二维数组的外边界元素?