当前位置:嗨网首页>书籍在线阅读

07-扩展属性操作

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

8.1.5 扩展属性操作

POSIX定义了应用程序可以对给定文件扩展属性执行的四种操作:

  • 给定文件,返回文件所有的扩展属性键的列表。
  • 给定文件和键,返回相应的值。
  • 给定文件,键与值,对键进行赋值。
  • 给定文件和键,从文件中删除对应的扩展属性。

对每个操作,POSIX提供三个系统调用:

  • 在给定路径名上执行操作的系统调用。如果路径指向符号链接,通常会在链接的目标文件上执行操作。
  • 在给定路径名上执行操作的系统调用。如果路径指向符号链接,也会在链接本身上执行操作(通常是以“l”开头的系统调用)。
  • 在文件描述符上执行操作的系统调用(一般为以“f”开头的系统调用)。

接下来,我们将讨论所有12种组合。

返回扩展属性

最简单的操作是返回文件扩展属性给定键的值,如下:

351.png getxattr()调用成功后,会将路径为path的文件中名字为key的扩展属性保存到缓冲区value中,该缓冲区的长度为size个字节。函数返回值为该值的实际大小。

如果size是0,调用会返回该值的大小,但不会把扩展属性保存到缓冲区value中。使用“0”,可以使应用程序确认存储键值的缓冲区的长度是否合适。获知大小后,应用程序会按需分配或调整缓冲区。

lgetxattr()与getxattr()行为一致。只是当路径为符号链接时,lgetxattr()返回的是链接本身而不是链接目标文件的扩展属性。大家回顾一下之前的讨论, 我们知道用户命名空间的属性不能被应用在符号链接上。因此,该调用很少被使用。

fgetxattr()在文件描述符fd上操作,其他方面,它的行为与getxattr()行为一致。

出错时,所有三个调用都返回-1,并相应设置errno值为下列值之一:

EACCES

调用的进程缺少对路径path中某一目录的搜索权限(仅适用于getxattr()和lgetxattr())。

EBADF fd非法(仅适用于fgetxattr())。

EFAULT path、key或value指针非法。

ELOOP路径path中包含太多符号链接(仅适用于getxattr()和lgetxattr()))。

ENAMETOOLONG 路径path太长(仅适用于getxattr()和lgetxattr())。

ENOATTR属性key不存在,或进程没有访问属性的权限。

ENOENT路径path中的某部分不存在(仅适用于getxattr()和lgetxattr())。

ENOMEM剩余内存不足,无法完成请求。

ENOTDIR路径path中的某个部分不是目录(仅适用于getxattr()和lgetxattr())。

ENOTSUP path或fd所在的文件系统不支持扩展属性。

ERANGE size太小,缓冲区无法保存键值。就像之前讨论的,调用可能将size设置为0,返回值将指明需要的缓存大小,并对value做适当的调整。

设置扩展属性

以下三个系统调用会设置给定的扩展属性:

352.png setxattr()调用成功时,会设置文件path的扩展属性key为value,value的长度为size字节。字段flags修改调用的行为。如果flags是 XATTR_CREATE,当扩展属性已存在时调用将失败。如果flags是XATTR_REPLACE,当扩展属性不存在时,调用将返回失败。默认的行为(即当 flags值为0时执行)是同时允许创建和替换。不管flags值如何,除了key之外,对其他键都不会有影响。

lsetxattr()与setxattr()行为一致,只是当path是符号链接,它会设置链接本身而不是链接目标文件的扩展属性。回顾一下之前的讨论, 我们知道用户命名空间的属性不能被应用在符号链接上。因此,该调用很少被使用。

fsetxattr()在文件描述符fd上执行操作,其他方面,它与setxattr()行为一致。

成功时,所有三个系统调用都返回0;失败时,都返回-1,并相应设置errno值为以下值之一:

EACCES

调用的进程缺少对路径path中某一目录的搜索权限(仅适用于setxattr()和lsetxattr())。

EBADF

fd非法(仅适用于fsetxattr())。

EDQUOT

由于配额限制,阻止请求操作使用空间。

EEXIST

flags设置为XATTR_CREATE,且给定文件中的key已存在。

EFAULT

Path、key或value指针非法。

EINVAL

flags非法。

ELOOP

路径path中包含太多符号链接(仅适用于setxattr()和lsetxattr())。

ENAMETOOLONG

路径path太长(仅适用于setxattr()和lsetxattr())。

ENOATTR

flags设置为XATTR_REPLACE,且给定的文件中不存在key。

ENOENT

路径path中的某部分不存在(仅适用于setxattr()和lsetxattr())。

ENOMEM

剩余内存不足,无法完成请求。

ENOSPC

文件系统剩余空间不足,无法存储扩展属性。

ENOTDIR

路径path中某部分不是目录(仅适用于setxattr()和lsetxattr())。

ENOTSUP

path或fd所在的文件系统不支持扩展属性。

列出文件的扩展属性

以下三个系统调用会列出给定文件扩展属性集:

353.png listxattr()调用成功时,会返回一个与路径path指定的文件相关联的扩展属性键列表。该列表存储在list指向的长度为size字节的缓冲区中。系统调用会返回列表的实际字节大小。

list中的每个扩展属性键是以'\0'结尾的,因此列表可能看起来如下:

354.png 因此,虽然每个键都是一个传统的、以'\0'结尾的C字符串,但是为了能够遍历整个键列表,还是需要整个列表的长度(可以从调用的返回值中获得该值)。为了确定所需缓冲区的大小,设置size为0并调用任意一个列表的函数,函数将返回整个键列表的实际长度。和调用getxattr()类似,应用程序可能使用这个功能来分配或调整缓冲区。

llistxattr()与listxattr()行为一致,只是当path为符号链接时,它会列出与链接本身而不是链接目标文件相关联的扩展属性。回顾一下之前的讨论,用户命名空间的属性不能被应用于符号链接——因此,该调用很少被使用。

flistxattr()对文件描述符fd进行操作,其他方面,它与listxattr()行为一致。

失败时,所有三个调用都返回-1,并相应设置errno值为以下值之一:

EACCES 调用的进程缺少对路径path中某一目录的搜索权限(仅适用于listxattr()和llistxattr())。

EBADF fd非法(仅适用于flistxattr())。

EFAULT path或list指针非法。

ELOOP 路径path中包含太多符号链接(仅适用于listxattr()和llistxattr())。

ENAMETOOLONG path过长(仅适用于listxattr()和llistxattr())。

ENOENT 路径path中的某个部分不存在(仅适用于listxattr()和llistxattr())。

ENOMEM 剩余内存不足,无法完成请求。

ENOTDIR 路径path中某部分不是目录(仅适用于listxattr()和llistxattr())。

ENOTSUPP path或fd所在的文件系统不支持扩展属性。

ERANGE size非零,且没足够大小存放整个键列表。应用程序可能设置size为0,调用后获得列表的实际大小。程序之后可能重置value,并重新调用该系统调用。

删除扩展属性

最后,以下3个系统调用可以从给定文件中删除指定键:

355.png 成功调用removexattr()会从文件path中删除扩展属性key。回顾之前讨论,未定义键与已定义但为空的键(零长度)有一定的区别。

lremovexattr()与removexattr()行为一致,除非path是符号链接,它会删除链接本身而不是链接目标文件的扩展属性。回顾之前,用户命名空间的属性不能被应用于符号链接,因此,该调用也很少被使用。

fremovexattr()操作文件描述符fd,其他方面,它与removexattr()行为一致。

成功时,所有3个系统调用返回0。失败时,所有3个调用返回-1,并相应设置errno值为下列值之一:

EACCES 调用的进程缺少对路径path中某一目录的搜索权限(仅适用于removexattr()和lremovexattr())。

EBADF fd非法(仅适用于fremovexattr())。

EFAULT path或key指针非法。

ELOOP路径path中包含太多符号链接。(仅适用于removexattr()和lremovexattr())。

ENAMETOOLONG path太长(仅适用于removexattr()和lremovexattr())。

ENOATTR给定文件不存在键key。

ENOENT路径path中的某部分不存在(仅适用于removexattr()和lremovexattr())。

ENOMEM剩余内存不足,无法完成请求。

ENOTDIR路径path中的某部分不是目录(仅适用于removexattr()和lremovexattr())。

ENOTSUPP path或fd所在的文件系统不支持扩展属性。