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 或某些其他文件系统拒绝打开这样的文件。