另外参见

chmod(1),chown(2),execve(2),open(2),stat(2),inode(7),path_resolution(7),symlink(7)

说明

chmod()和fchmod()系统调用更改文件模式位。 (文件模式由文件许可权位,设置用户标识,设置组标识和粘性位组成。)这些系统调用仅在指定文件的方式上有所不同:

*
chmod()更改指定的文件模式,该文件的路径名在路径名中给出,如果它是符号链接,则取消引用。
*
fchmod()更改打开文件描述符fd引用的文件的模式。

新文件模式是在模式下指定的,该模式是通过将以下零个或多个值进行或运算而创建的位掩码:

S_ISUID(04000)
set-user-ID(在execve(2)上设置进程有效用户ID)
S_ISGID(02000)
set-group-ID(在execve(2)上设置进程有效的组ID;强制锁定,如fcntl(2)中所述;从父目录中获取新文件的组,如chown(2)和mkdir(2)中所述))
S_ISVTX(01000)
粘性位(受限制的删除标志,如unlink(2)中所述)
S_IRUSR(00400)
所有者阅读
S_IWUSR(00200)
由所有者写
S_IXUSR(00100)
由所有者执行/搜索("搜索"适用于目录,表示可以访问目录中的条目)
S_IRGRP(00040)
按组阅读
S_IWGRP(00020)
按组写
S_IXGRP(00010)
按组执行/搜索
S_IROTH(00004)
别人读
S_IWOTH(00002)
别人写
S_IXOTH(00001)
他人执行/搜索

调用进程的有效UID必须与文件的所有者匹配,否则该进程必须具有特权(Linux:它必须具有CAP_FOWNER功能)。

如果调用进程没有特权(Linux:不具有CAP_FSETID功能),并且文件的组与该进程的有效组ID或其补充组ID之一不匹配,则S_ISGID位将关闭,但这不会导致返回错误。

作为安全措施,取决于文件系统,如果写入文件,则可能会关闭设置用户ID和设置组ID执行位。 (在Linux上,如果写入过程不具有CAP_FSETID功能,则会发生这种情况。)在某些文件系统上,只有超级用户才能设置粘性位,这可能具有特殊含义。有关粘性位以及目录上的set-user-ID和set-group-ID位,请参见inode(7)。

在NFS文件系统上,限制访问权限将立即影响已经打开的文件,因为访问控制是在服务器上完成的,但是打开的文件由客户端维护。如果其他客户端启用了属性缓存,则扩展权限可能会延迟。

fchmodat()

除了此处描述的差异之外,fchmodat()系统调用的操作与chmod()完全相同。

如果在路径名中给定的路径名​​是相对的,则它相对于文件描述符dirfd所引用的目录进行解释(而不是相对于调用进程的当前工作目录,如chmod()对相对路径名所做的那样) 。

如果路径名是相对的,并且dirfd是特殊值AT_FDCWD,则路径名将相对于调用进程的当前工作目录(例如chmod())进行解释。

如果路径名是绝对的,则dirfd被忽略。

标志可以是0,也可以包含以下标志:

AT_SYMLINK_NOFOLLOW
如果路径名是符号链接,请不要取消引用它:而是对链接本身进行操作。当前未实现此标志。

有关对fchmodat()的需求的说明,请参见openat(2)。

CHMOD - Linux手册页

Linux程序员手册 第2部分
更新日期: 2017-09-15

版本

fchmodat()在内核2.6.16中添加到Linux;库支持已添加到版本2.4中的glibc。

错误说明

根据文件系统,可能会返回除以下所列错误以外的其他错误。

chmod()的更常见错误如下所示:

EACCES
在路径前缀的组件上拒绝搜索许可。 (另请参见path_resolution(7)。)
EFAULT
路径名指向您可访问的地址空间之外。
EIO
发生I / O错误。
ELOOP
解析路径名时遇到太多符号链接。
ENAMETOOLONG
路径名太长。
ENOENT
该文件不存在。
ENOMEM
内核内存不足。
ENOTDIR
路径前缀的组成部分不是目录。
EPERM
有效的UID与文件的所有者不匹配,并且该进程没有特权(Linux:它不具有CAP_FOWNER功能)。
EPERM
该文件被标记为不可变或仅附加。 (请参阅ioctl_iflags(2)。)
EROFS
命名文件驻留在只读文件系统上。

下面列出了fchmod()的一般错误:

EBADF
文件描述符fd无效。
EIO
往上看。
EPERM
往上看。
EROFS
往上看。

对于chmod()发生的相同错误也可能对于fchmodat()发生。 fchmodat()可能会发生以下其他错误:

EBADF
dirfd不是有效的文件描述符。
EINVAL
标志中指定的标志无效。
ENOTDIR
pathname是相对的,dirfd是引用目录以外的文件的文件描述符。
ENOTSUP
指定的标志AT_SYMLINK_NOFOLLOW,不支持。

名称

chmod,fchmod,fchmodat-更改文件的权限

返回值

成功时,返回零。如果出错,则返回-1,并正确设置errno。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

语法

#include <sys/stat.h>

int chmod(const char *pathname, mode_t mode);

int fchmod(int fd, mode_t mode);

#include <fcntl.h>           /* Definition of AT_* constants */
#include <sys/stat.h>

int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

fchmod():

Since glibc 2.24:
_POSIX_C_SOURCE &gt;= 199309L

Glibc 2.19至2.23
_POSIX_C_SOURCE

Glibc 2.16至2.19:
_BSD_SOURCE _POSIX_C_SOURCE

Glibc 2.12至2.16:
_BSD_SOURCE _XOPEN_SOURCE> = 500
_POSIX_C_SOURCE> = 200809L

Glibc 2.11和更早版本:
_BSD_SOURCE _XOPEN_SOURCE> = 500

fchmodat():

Since glibc 2.10:
_POSIX_C_SOURCE>= 200809L
Before glibc 2.10:
_ATFILE_SOURCE

遵循规范

chmod(),fchmod():4.4BSD,SVr4,POSIX.1-2001i,POSIX.1-2008。

fchmodat():POSIX.1-2008。

备注

C library/kernel differences

GNU C库fchmodat()包装函数实现了本页中描述的POSIX指定的接口。此接口与基础Linux系统调用不同,后者没有标志参数。

Glibc notes

在无法使用fchmodat()的旧内核上,glibc包装器功能会退回到chmod()的使用。如果路径名是相对路径名,则glibc将基于/ proc / self / fd中与dirfd参数相对应的符号链接构造路径名。

日期:2019-08-20 17:58:41 来源:oir作者:oir