open() 函数参数
open() function parameters
如果您在考虑最后一个参数“0”的情况下查看下面的代码块,写行是否正常工作?
filename = argv[1];
string = "Example string";
if (stat(argv[1], &buf) != 0)
{
fd = open(filename, O_WRONLY | O_CREAT, 0);
if (fd < 0)
{
perror(filename);
exit(1);
}
write(fd, string, strlen(string));
close(fd);
}
else
{
print("%s file exists\n", filename);
}
有效,
这来自 open(2)
Linux 手册页
The mode argument specifies the file mode bits be applied when a new file is created. This argument must be supplied when O_CREAT
or O_TMPFILE
is specified in flags; if neither O_CREAT
nor O_TMPFILE
is specified, then mode is ignored. The effective mode is modified by the process's umask in the usual way: in the absence of a default ACL, the mode of the created file is (mode & ~umask). Note that this mode applies only to future accesses of the newly created file; the open() call that creates a read-only file may well return a read/write file descriptor.
那么理论上,在您调用 close()
之前,您对该文件的访问是有效的,因为我理解我在上面摘录中突出显示的部分。
来自联机帮助页:
mode
specifies the permissions to use in case a new file is created. This argument must be supplied when O_CREAT
is specified in flags; if O_CREAT
is not specified, then mode
is ignored. The effective permissions are modified by the process's umask in the usual way: The permissions of the created file are (mode & ~umask
). Note that this mode applies only to future accesses of the newly created file; the open()
call that creates a read-only file may well return a read/write file descriptor.
The following symbolic constants are provided for mode:
S_IRWXU 00700 user (file owner) has read, write and execute permission
S_IRUSR 00400 user has read permission
S_IWUSR 00200 user has write permission
S_IXUSR 00100 user has execute permission
S_IRWXG 00070 group has read, write and execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 others have read, write and execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
因此,指定 mode
为零,您将创建一个具有 0 & ~umask
权限的文件 ,即文件 没有任何权限.
文件系统对此的具体内容不在 open()
或 write()
函数的范围内。
有趣的问题。 POSIX 说:
The argument following the oflag argument does not affect whether the file is open for reading, writing, or for both.
这意味着由于您正在处理来自 open
的错误 return,如果您到达 write
行,则行为已明确定义。
进一步说明为什么会这样。在类 unix 系统上的大多数文件系统上,与文件相关的元数据不应影响已经打开的文件描述符。例如,您可以删除已打开的文件。这实际上对临时文件很常见,因此您不需要记住在退出时删除它们。这同样适用于文件的权限甚至所有权。事实上,您可以 chroot
在打开文件的同时仍然可以写入它而实际上看不到它。您甚至可以使用文件描述符传递将打开的文件描述符提供给不允许打开该文件的另一个进程。这通常用于特权分离。无论以后对权限的更改如何,您在创建文件描述符时拥有的权限都是有效的。所以你的问题是一个非常有趣的边缘案例,因为它询问文件的文件系统权限是在我们为它创建文件描述符之前还是之后设置的,POSIX 似乎很清楚。
我现在只能想到两个例外。首先是当有人强行将文件系统重新挂载为只读时,在这种情况下,内核将通过可怕的体操来使您的文件描述符无效,这将导致其所有操作失败。第二个是 AFS,当您关闭文件时(或者,当您本地系统上文件的最后一个用户关闭它并将其发送到服务器时),您的权限实际上会被检查,这会导致您的时间限制访问的搞笑问题令牌在您打开文件时有效,但在您关闭文件时不再有效。这也是 close
returns 错误的原因(但那是另一个咆哮)。
这就是我在上面提到错误处理的原因。尽管 POSIX 说它不应该有影响,但我可以看到 AFS 或某些其他文件系统拒绝打开这样的文件。
如果您在考虑最后一个参数“0”的情况下查看下面的代码块,写行是否正常工作?
filename = argv[1];
string = "Example string";
if (stat(argv[1], &buf) != 0)
{
fd = open(filename, O_WRONLY | O_CREAT, 0);
if (fd < 0)
{
perror(filename);
exit(1);
}
write(fd, string, strlen(string));
close(fd);
}
else
{
print("%s file exists\n", filename);
}
有效,
这来自 open(2)
Linux 手册页
The mode argument specifies the file mode bits be applied when a new file is created. This argument must be supplied when
O_CREAT
orO_TMPFILE
is specified in flags; if neitherO_CREAT
norO_TMPFILE
is specified, then mode is ignored. The effective mode is modified by the process's umask in the usual way: in the absence of a default ACL, the mode of the created file is (mode & ~umask). Note that this mode applies only to future accesses of the newly created file; the open() call that creates a read-only file may well return a read/write file descriptor.
那么理论上,在您调用 close()
之前,您对该文件的访问是有效的,因为我理解我在上面摘录中突出显示的部分。
来自联机帮助页:
mode
specifies the permissions to use in case a new file is created. This argument must be supplied whenO_CREAT
is specified in flags; ifO_CREAT
is not specified, thenmode
is ignored. The effective permissions are modified by the process's umask in the usual way: The permissions of the created file are (mode & ~umask
). Note that this mode applies only to future accesses of the newly created file; theopen()
call that creates a read-only file may well return a read/write file descriptor.The following symbolic constants are provided for mode:
S_IRWXU 00700 user (file owner) has read, write and execute permission S_IRUSR 00400 user has read permission S_IWUSR 00200 user has write permission S_IXUSR 00100 user has execute permission S_IRWXG 00070 group has read, write and execute permission S_IRGRP 00040 group has read permission S_IWGRP 00020 group has write permission S_IXGRP 00010 group has execute permission S_IRWXO 00007 others have read, write and execute permission S_IROTH 00004 others have read permission S_IWOTH 00002 others have write permission S_IXOTH 00001 others have execute permission
因此,指定 mode
为零,您将创建一个具有 0 & ~umask
权限的文件 ,即文件 没有任何权限.
文件系统对此的具体内容不在 open()
或 write()
函数的范围内。
有趣的问题。 POSIX 说:
The argument following the oflag argument does not affect whether the file is open for reading, writing, or for both.
这意味着由于您正在处理来自 open
的错误 return,如果您到达 write
行,则行为已明确定义。
进一步说明为什么会这样。在类 unix 系统上的大多数文件系统上,与文件相关的元数据不应影响已经打开的文件描述符。例如,您可以删除已打开的文件。这实际上对临时文件很常见,因此您不需要记住在退出时删除它们。这同样适用于文件的权限甚至所有权。事实上,您可以 chroot
在打开文件的同时仍然可以写入它而实际上看不到它。您甚至可以使用文件描述符传递将打开的文件描述符提供给不允许打开该文件的另一个进程。这通常用于特权分离。无论以后对权限的更改如何,您在创建文件描述符时拥有的权限都是有效的。所以你的问题是一个非常有趣的边缘案例,因为它询问文件的文件系统权限是在我们为它创建文件描述符之前还是之后设置的,POSIX 似乎很清楚。
我现在只能想到两个例外。首先是当有人强行将文件系统重新挂载为只读时,在这种情况下,内核将通过可怕的体操来使您的文件描述符无效,这将导致其所有操作失败。第二个是 AFS,当您关闭文件时(或者,当您本地系统上文件的最后一个用户关闭它并将其发送到服务器时),您的权限实际上会被检查,这会导致您的时间限制访问的搞笑问题令牌在您打开文件时有效,但在您关闭文件时不再有效。这也是 close
returns 错误的原因(但那是另一个咆哮)。
这就是我在上面提到错误处理的原因。尽管 POSIX 说它不应该有影响,但我可以看到 AFS 或某些其他文件系统拒绝打开这样的文件。