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;
}
でmode
あるst_mode
とlstat(path...)
。
つまり、システムがサポートしている場合、上記の関数はファイルまたはシンボリックリンクのモードを設定しようとするはずです。そうでない場合は、正常に戻る必要があります。
そのため、EOPNOTSUPP
POSIX で指定されているエラーをチェックしています。
[EOPNOTSUPP]
フラグ引数で AT_SYMLINK_NOFOLLOW ビットが設定され、パス名がシンボリック リンクであり、システムがシンボリック リンクのモードの変更をサポートしていません。
EINVAL
ただし、どちらが次のように指定されているかは少し心配です。
[EINVAL]
フラグ引数の値が無効です。
AT_SYMLINK_NOFOLLOW
理論的には、特定のファイル システムがシンボリック リンクのモード ビットの設定をサポートしていない場合、実際には無効なフラグとして扱われる可能性があると思います。
一方、EOPNOTSUPP
エラーの説明とフラグの記述方法は次のとおりです。
flag の値は、 で定義されている次のリストのフラグのビットごとの包括的 OR によって構築されます。
AT_SYMLINK_NOFOLLOW
path がシンボリック リンクを指定する場合、シンボリック リンクのモードが変更されます。
このフラグは、準拠した実装によって常に有効に扱われるべきだと思います。
私は正しいですか、またはchmod()
の場合にフォールバックを実装する必要がありEINVAL
ますか?
編集:注意として、パスがシンボリックリンクを指定していなくても、Linuxが使用されるたびENOTSUP
に(と同じ値を持つ)を返すことがわかりました。EOPNOTSUPP
AT_SYMLINK_NOFOLLOW