【问题标题】:How to get extended attributes of a file(UNIX/C)?如何获取文件的扩展属性(UNIX/C)?
【发布时间】:2016-07-13 18:14:19
【问题描述】:

当我在命令行中输入ls -l 时,有时会在文件权限旁边出现@+ 符号(顺便说一句,我在OS X 上),如下所示:

-rw-r-----@  1 john  staff      6731 Sep 28 01:10 mutations.txt
drwxr-xr-x+ 71 john  staff      2414 Mar 25 18:16 ..

我知道如何使用stat 结构获取权限位,但我认为这些扩展权限值不存在。有人可以为我指出如何通过 C 或 POSIX API 获取这些值的正确方向吗?

编辑

我尝试了以下方法:

#include <sys/types.h>
#include <sys/xattr.h>
#include <sys/types.h>

int main () {
    char  l[1024];
    listxattr("/Users/john/desktop/mutations.txt", l, 1024,  XATTR_SHOWCOMPRESSION);

    printf("%s\n", l);
}

并得到输出:

com.apple.metadata:kMDItemWhereFroms

仍在尝试了解如何将其转换为 @+

【问题讨论】:

  • 另外,为了让您知道,您包含了两次 &lt;sys/types.h&gt;。不确定这是否是设计使然。

标签: c macos unix permissions xattr


【解决方案1】:

@ 表示文件具有扩展属性。使用listxattr() 获取所有扩展属性的名称列表,使用getxattr() 获取特定属性的值。如果listxattr 返回非零结果,您将显示@ 来表明这一点。

扩展属性不在 POSIX 中,但这个 API 至少在 Linux 和 OS X 中可用。

您可以找到如何使用这些函数的示例here

+ 表示文件有访问控制列表。在某些文件系统中,这被存储为特殊的扩展属性;在其他情况下,它是单独存储的。有关访问控制列表,请参阅 acl(5) 以获取参考,您可以找到显示它的示例程序 here

【讨论】:

  • 你能举个例子说明如何获得@或+符号吗?我阅读了文档,并尝试了链接,我得到了:com.apple.metadata:kMDItemWhereFroms。关于这意味着什么的任何想法?
  • @+ 不是来自任何地方。如果ls 检测到文件具有扩展属性或 ACL,它们只会显示出来。
  • 要获得任何特定属性的含义,您必须搜索它。我不知道一个完整的列表。
  • 我尝试更新了这个问题。所以在像上面这样的情况下,我得到一些输出,这是否意味着文件具有扩展属性? ACL 呢?
  • 我通过谷歌搜索在我的答案中找到了信息。你真的弱到不能自己做一点调查吗?
【解决方案2】:

以下是我从 Apple 提供的 ls 的官方实现中抓取的一些代码,您将找到 here。代码很长,所以 CMD + F 并搜索“printlong”。

#include <sys/types.h>
#include <sys/xattr.h>
#include <sys/types.h>
#include <sys/acl.h>
#include <stdio.h>

int main () {
    acl_t acl = NULL;
    acl_entry_t dummy;
    ssize_t xattr = 0;
    char chr;
    char * filename = "/Users/john/desktop/mutations.txt";

    acl = acl_get_link_np(filename, ACL_TYPE_EXTENDED);
    if (acl && acl_get_entry(acl, ACL_FIRST_ENTRY, &dummy) == -1) {
        acl_free(acl);
        acl = NULL;
    }
    xattr = listxattr(filename, NULL, 0, XATTR_NOFOLLOW);
    if (xattr < 0)
        xattr = 0;

    if (xattr > 0)
        chr = '@';
    else if (acl != NULL)
        chr = '+';
    else
        chr = ' ';

    printf("%c\n", chr);
 }

根据所使用的文件,输出将为空白、@ 或 +,其方式与 ls -l 显示它的方式完全相同。希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    相关资源
    最近更新 更多