【问题标题】:Can AT_SYMLINK_NOFOLLOW cause an EINVAL from fchmodat()?AT_SYMLINK_NOFOLLOW 会导致 fchmodat() 的 EINVAL 吗?
【发布时间】:2012-09-12 21:46:53
【问题描述】:

我正在阅读fchmodat() POSIX function spec,但不确定以下内容是否正确:

#include <fcntl.h>
#include <sys/stat.h>

int chown_test(const char* path, mode_t mode, mode_t new_mode)
{
#ifdef HAVE_FCHMODAT
    if (fchmodat(AT_FDCWD, path, new_mode,
                AT_SYMLINK_NOFOLLOW) && errno != EOPNOTSUPP)
        return 1;
#else
    if (!S_ISLNK(mode) && chmod(path, new_mode))
        return 1;
#endif

    return 0;
}

modest_modelstat(path...)

换句话说,如果系统支持,上述函数应该尝试设置文件或符号链接的模式。如果没有,它应该优雅地返回。

因此,我正在检查 POSIX 指定的 EOPNOTSUPP 错误:

[EOPNOTSUPP]

标志参数中设置了AT_SYMLINK_NOFOLLOW位,路径命名符号链接,系统不支持更改符号链接的模式。

不过,我有点担心EINVAL 被指定为:

[EINVAL]

标志参数的值无效。

理论上,如果特定文件系统不支持设置符号链接的模式位,我认为它实际上可以将AT_SYMLINK_NOFOLLOW 视为无效标志。

另一方面,EOPNOTSUPP 错误描述和标志的描述方式:

标志的值由以下列表中标志的按位或构成,定义在:

AT_SYMLINK_NOFOLLOW

如果路径命名符号链接,则符号链接的模式会改变。

让我觉得这个标志应该始终被兼容的实现视为有效。

我是正确的还是应该在EINVAL 的情况下回退到chmod()


编辑:作为说明,我刚刚发现 Linux 会在使用 AT_SYMLINK_NOFOLLOW 时返回 ENOTSUP(与 EOPNOTSUPP 具有相同的值),即使路径 没有命名符号链接。

【问题讨论】:

  • 我读到说AT_SYMLINK_NOFOLLOW 在一致性实现中始终是一个有效标志。不过,这是个好问题。

标签: c posix


【解决方案1】:

相关文字为 XSH 2.3 Error Numbers:

实现可能支持未包含在此列表中的其他错误,可能会在此处描述之外的情况下生成此列表中包含的错误,或者可能包含防止某些错误发生的扩展或限制。

起初这似乎允许所描述的行为。但是我相信下面的文字:

如果且仅当所有这些错误条件始终与本卷 POSIX.1-2008 中描述的错误条件相同时,实施可能会在此处列出的错误编号中生成错误编号。对于本卷 POSIX.1-2008 中描述的错误情况,实现不应生成与本卷 POSIX.1-2008 要求的错误编号不同的错误编号,但可能会产生额外的错误,除非明确禁止特定功能。

呈现一个实现,该实现给出EINVAL,因为此条件不符合要求。 POSIX 将 EOPNOTSUPP 指定为该条件的错误代码,因此实现“不应”(这是规范要求)为其生成不同的错误代码。

来源:http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_03

【讨论】:

  • 错误,在 Linux 上 ENOTSUPEOPNOTSUPP 具有相同的值。
  • 我的意思是EOPNOTSUPP。我会解决的。
  • @R:你为什么认为 Linux 坏了?问题中甚至没有提到 Linux...
  • 对不起,我一定是把我对这个问题的阅读与另一个关于 Linux 的问题交叉起来,并认为这个问题是关于 Linux 所展示的某些行为而不是理论上的可能性。我已经确定了答案。
猜你喜欢
  • 2016-12-09
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多