path_resolution() - Unix、Linux 系统调用
Tutorials Point


  Unix 初学者指南
  Unix Shell 编程
  高级 Unix
  Unix 有用参考
  Unix 有用资源
  精选阅读

版权所有 © 2014 tutorialspoint



  首页     参考     讨论论坛     关于TP  

path_resolution() - Unix、Linux 系统调用


previous next AddThis Social Bookmark Button

广告

名称

Unix/Linux 路径解析 - 查找文件名所引用的文件

描述

一些 Unix/Linux 系统调用以一个或多个文件名作为参数。文件名(或路径名)解析如下。

步骤 1:解析过程的开始

如果路径名以“/”字符开头,则起始查找目录为当前进程的根目录。(进程从其父进程继承其根目录。通常这将是文件层次结构的根目录。进程可以通过使用chroot(2)系统调用获得不同的根目录。如果进程(或其祖先之一)是由clone(2)系统调用的调用启动的,并且设置了 CLONE_NEWNS 标志,则进程可能会获得一个完全私有的命名空间。)这处理路径名的“/”部分。

如果路径名不以“/”字符开头,则解析过程的起始查找目录是进程的当前工作目录。(这也从父进程继承而来。可以通过使用chdir(2)系统调用来更改它。)

以“/”字符开头的路径名称为绝对路径名。不以“/”开头的路径名称为相对路径名。

步骤 2:沿着路径行走

将当前查找目录设置为起始查找目录。现在,对于路径名的每个非最终组件(其中组件是由“/”字符分隔的子字符串),将在当前查找目录中查找此组件。

如果进程在当前查找目录上没有搜索权限,则返回 EACCES 错误(“权限被拒绝”)。

如果找不到该组件,则返回 ENOENT 错误(“没有这样的文件或目录”)。

如果找到该组件,但它既不是目录也不是符号链接,则返回 ENOTDIR 错误(“不是目录”)。

如果找到该组件并且是目录,我们将当前查找目录设置为该目录,然后转到下一个组件。

如果找到该组件并且是符号链接(符号链接),我们首先解析此符号链接(以当前查找目录作为起始查找目录)。发生错误时,将返回该错误。如果结果不是目录,则返回 ENOTDIR 错误。如果符号链接的解析成功并返回一个目录,我们将当前查找目录设置为该目录,然后转到下一个组件。请注意,此处的解析过程涉及递归。为了保护内核免受堆栈溢出的影响,以及为了防止拒绝服务,对最大递归深度和跟随的最大符号链接数有限制。当超过最大值时,将返回 ELOOP 错误(“符号链接级别过多”)。

步骤 3:查找最终条目

路径名的最终组件的查找与前一步中描述的所有其他组件的查找相同,有两个区别:(i)最终组件不必是目录(至少就路径解析过程而言 - 它可能必须是目录或非目录,因为特定系统调用的要求),以及(ii)如果找不到该组件,则不一定是错误 - 也许我们只是在创建它。特定系统调用的手册页中描述了对最终条目的处理细节。

。和 ..

按照惯例,每个目录都有条目“.”和“..”,它们分别指代目录本身及其父目录。

路径解析过程将假定这些条目具有其常规含义,无论它们是否实际存在于物理文件系统中。

无法向下遍历根目录:“/..”与“/”相同。

挂载点

在执行“mount dev path”命令后,路径名“path”将引用设备“dev”上的文件系统层次结构的根目录,而不是它之前引用的任何内容。

可以从已挂载的文件系统中退出:“path/..”引用“path”的父目录,位于“dev”上的文件系统层次结构之外。

尾部斜杠

如果路径名以“/”结尾,则强制解析前面的组件,如步骤 2 中所述:它必须存在并解析为目录。否则将忽略尾随“/”。(或者,等效地,以“/”结尾的路径名等效于通过在其后附加“.”获得的路径名。)

最终符号链接

如果路径名的最后一个组件是符号链接,则取决于系统调用引用的文件是符号链接还是其内容上的路径解析结果。例如,系统调用lstat(2)将对符号链接进行操作,而stat(2)将对符号链接指向的文件进行操作。

长度限制

路径名有最大长度。如果路径名(或在解析符号链接时获得的一些中间路径名)过长,则返回 ENAMETOOLONG 错误(“文件名过长”)。

空路径名

在原始 Unix 中,空路径名引用当前目录。现在 POSIX 规定不得成功解析空路径名。Linux 在这种情况下返回 ENOENT。

权限

文件的权限位由三组三个位组成,参见chmod(1)和stat(2)。当当前进程的有效用户 ID 等于文件的拥有者 ID 时,使用前三组。当文件的组 ID 等于当前进程的有效组 ID 或当前进程的补充组 ID 之一时(由setgroups(2)设置),使用第二组三个。当两者都不成立时,使用第三组。

在使用的三个位中,第一个位确定读取权限,第二个位确定写入权限,最后一个位确定普通文件的情况下的执行权限或目录的情况下的搜索权限。

Linux 使用 fsuid 而不是有效用户 ID 进行权限检查。通常,fsuid 将等于有效用户 ID,但可以通过系统调用setfsuid(2)更改 fsuid。

(此处“fsuid”代表类似“文件系统用户 ID”的东西。该概念是在用户空间 NFS 服务器实现中所需的,当时进程可以向具有相同有效用户 ID 的进程发送信号。它现在已过时。没有人应该使用setfsuid(2)。)

类似地,Linux 使用 fsgid(“文件系统组 ID”)而不是有效组 ID。请参阅setfsgid(2)。

绕过权限检查:超级用户和功能

在传统的 Unix 系统上,超级用户(root,用户 ID 0)拥有至高无上的权力,并在访问文件时绕过所有权限限制。

在 Linux 上,超级用户权限被划分为功能(请参阅capabilities(7))。两个功能与文件权限检查相关:CAP_DAC_OVERRIDE 和 CAP_DAC_READ_SEARCH。(如果进程的 fsuid 为 0,则该进程具有这些功能。)

CAP_DAC_OVERRIDE 功能覆盖所有权限检查,但仅在文件的三个执行权限位中至少设置了一个时才授予执行权限。

CAP_DAC_READ_SEARCH 功能授予对目录的读取和搜索权限,以及对普通文件的读取权限。

另请参阅



previous next Printer Friendly

广告


  

广告



广告