AT_SYMLINK_NOFOLLOW是否会导致fchmodat()返回EINVAL?

3

我正在阅读fchmodat() POSIX函数规范,但我不确定以下内容是否正确:

#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;
}

使用lstat(path ...)mode来表示模式。

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

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

[EOPNOTSUPP]

在flag参数中设置了AT_SYMLINK_NOFOLLOW位,路径名是符号链接,并且系统不支持更改符号链接的模式。

但是,我有点担心指定为EINVAL的情况:

[EINVAL]

标志参数的值无效。

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

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

标记的值通过以下列表中定义的标记的按位包含OR构造:

AT_SYMLINK_NOFOLLOW

如果路径名是符号链接,则更改符号链接的模式。

让我认为,遵守规范的实现应始终将此标志视为有效。

我是正确的,还是应该在EINVAL的情况下实施chmod()回退?


编辑:注意,我刚刚发现,即使路径不是符号链接,Linux也会在使用AT_SYMLINK_NOFOLLOW时返回ENOTSUP(具有与EOPNOTSUPP 相同的值)。


我读到的意思是,在符合规范的实现中,“AT_SYMLINK_NOFOLLOW”始终是一个有效的标志。不过,这是个好问题。 - Nemo
1个回答

0

相关文本为XSH 2.3错误编号:

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

起初,这似乎允许所描述的行为。然而,我相信紧接着下面的文字:

如果且仅当所有这些错误条件始终可以与 POSIX.1-2008 的本卷所述的错误条件完全相同地处理时,实现才可以在除此处描述的情况之外生成此处列出的错误编号。对于 POSIX.1-2008 本卷中描述的错误条件,实现不得生成与所需错误编号不同的错误编号,但可以生成其他错误,除非特定函数明确禁止。

使得对于此条件给出 EINVAL 的实现是不符合标准的。POSIX 指定 EOPNOTSUPP 作为此条件的错误代码,因此实现“不得”(这是一项规范要求)为其生成不同的错误代码。

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


错误,在Linux系统中,“ENOTSUP”与“EOPNOTSUPP”具有相同的值。 - Michał Górny
我是指 EOPNOTSUPP。我会修复它。 - R.. GitHub STOP HELPING ICE
@R:你为什么认为Linux出了问题?问题中甚至没有提到Linux... - Nemo
抱歉,我可能将这个问题的阅读与另一个关于Linux的问题混淆了,认为这个问题是关于Linux表现出的某种行为而不是理论上的可能性。我已经修正了我的答案。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接