设置O_CREAT位但仅提供两个open参数会发生什么?

问题描述

Here,我问的是为sys_open实现OS161的系统调用的工作,该系统调用将由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,mode_t mode);

由于它是一个可变参数函数,它可以接受传递的参数个数,但仅定义具有2个或3个参数的情况。

我的问题是如何确定传递给open的参数数量,是2还是3。答案是,如果flags中的O_CREAT位置1,则{{1 }}。

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

mode

在这种情况下,fd = open(filename,O_WRONLY|O_CREAT|O_Trunc); 的值将是mode寄存器中的值,而不是有效值。

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

我曾经让a2函数接收3个参数,并且仅在sys_open位置1时才使用最后一个mode)。但是,由于现在可以在没有设置第三个参数的情况下调用函数,因此即使无效,我仍然可以使用O_CREAT的值。

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

上面提到的问题中详细介绍了发出系统调用的方式。

解决方法

POSIX文档仅声明:

mode应该设置为oflag自变量之后的自变量的值,其类型为mode_t,修改如下:...

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


Linux文档对此有此说法(我强调):

如果在mode中指定了O_CREATO_TMPFILE,则必须提供flags自变量 如果未提供,则将从堆栈中获取任意字节作为文件模式。

现在,这已经不是标准文件了,其中“必须”一词是您执行此操作的明确要求(否则所有赌注都与效果无关),但您可能应该阅读以这种方式。因此,再次,您应该确保提供它。

所以我想说您的处理方式如下:

  • 如果在客户/主叫方,请确保提供此模式。还有其他违反合同的事。
  • 在服务器/被调用方,假定调用方已提供它,因为如果没有,则表明他们正在违反合同。 POSIX中似乎没有合适的错误返回信息(在“必须失败”或“可能失败”部分),即使您可以检测到该错误,它也仍然适合指示此问题。