【问题标题】:What happens when setting the O_CREAT bit but only providing two parameters for open()? [duplicate]设置 O_CREAT 位但只为 open() 提供两个参数时会发生什么? [复制]
【发布时间】:2020-12-24 11:36:07
【问题描述】:

Here,我在询问为OS161 实现sys_open 系统调用的分配,该系统调用将由open 函数调用。

open函数的定义如下:

int open(const char *filename, int flags, ...);

手册页如下所示:

概要

#include <unistd.h>
#include <fcntl.h>

int
open(const char *filename, int flags);
int
open(const char *filename, int flags, mode_t mode);

由于它是一个可变参数函数,它可以接受尽可能多的参数,但只定义了具有 2 个或 3 个参数的情况。

我的问题是如何确定传递给open 的参数数量,是2 还是3。如果在flags 中设置了O_CREAT 位,则提供mode 的答案方式。

但我在操作系统中看到了一些看起来像这样的代码:

fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC);

在这种情况下,mode 的值将是 a2 寄存器中的任何值,而不是有效值。

1 - 在这种情况下会发生什么,在这种情况下我应该怎么做?参数如何传递?它是否在a2 寄存器中传递了一个零(不太可能发生)?或者它只是留下寄存器中的任何值?无论如何,如何确定最后一个参数是否有效?

我曾经让 sys_open 函数接收 3 个参数,并且如果设置了 O_CREAT 位,则仅使用最后一个 (mode)。但是现在由于可以使用设置的位并且没有第三个参数来调用该函数,因此即使 mode 的值无效,我仍然可以使用它。

2 - 处理参数的逻辑应该是什么?

系统调用的发出方式在上述问题中有详细说明。

【问题讨论】:

标签: c operating-system kernel mips system-calls


【解决方案1】:

POSIX 文档仅声明:

mode 应设置为oflag 参数后面的参数值,类型为mode_t 修改如下:...

它没有指定当您省略该参数时会发生什么,因此建议您确保它存在(在客户端)。最可能的情况是它将使用参数所在的(无论是在寄存器中还是在内存中,取决于调用约定),以及这种情况的可能性正确的值应该很小。


Linux 文档对此有这样的说法(我的重点):

如果在flags 中指定了O_CREATO_TMPFILE,则必须提供mode 参数必须如果不提供,堆栈中的一些任意字节将被应用为文件模式。

现在,当然,这不是一个标准文档,其中“必须”一词是您执行此操作的可靠要求(否则所有关于效果的赌注都是错误的),但您可能应该阅读 以这种方式。因此,同样,您应该确保提供它。

所以我会说你的处理方式如下:

  • 如果在客户端/调用方,请确保提供模式。其他任何事情都是违反合同的。
  • 在服务器/被调用方方面,假设调用方提供了它,因为如果他们没有提供,他们就违反了合同。 POSIX 中似乎没有合适的错误返回(在“将失败”或“可能失败”部分)适合指示此问题,即使您可以检测到它。李>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    相关资源
    最近更新 更多