【发布时间】: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;
}
mode 是 st_mode 的 lstat(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在一致性实现中始终是一个有效标志。不过,这是个好问题。