2017-02-14 63 views
0

我写了下面的C代码来打开一个不存在的文件。在C中使用open()函数创建的文件的默认访问模式是什么?

#include<stdio.h> 
#include<fcntl.h> 
#include<unistd.h> 
#include<sys/stat.h> 
#include<sys/types.h> 

int main(){ 
    int fd = open("test.c",O_WRONLY | O_CREAT); 
    printf("%d\n",fd); 
    close(fd); 
} 

虽然当我运行ls -l命令的umask设置为0002,我得到我创建的文件下面的输出。

-r--rws--T 1 urohit011 urohit011  0 Feb 14 22:35 test.c 

当我用新的文件名运行代码时,访问模式发生变化。我在这里有两个问题。

  • 由于umask 是0002,该文件的默认访问模式不应该是664吗?
  • 为什么访问模式在代码运行时改变了新文件名 ?
+0

你确定要使用''test.c“'作为文件名吗?我希望你不会覆盖你的源文件。 –

+0

@Someprogrammerdude我不认为名称“test.c”应该是一个问题,因为它在执行程序之前不存在。 –

回答

4

mode /许可位由调用的第三个参数open指定。你不提供这样的说法,这是当使用O_CREAT无声编程错误:

这种说法(mode)当flags指定O_CREATO_TMPFILE必须提供;如果既没有指定O_CREAT也没有指定O_TMPFILE,则忽略mode


不该该文件的缺省访问模式是664,因为umask是必须明确提供0002

默认mode

open("test.c",O_WRONLY | O_CREAT, 0666) 
            ^^ 

为什么当代码以新文件名运行时访问模式会改变?

openvariadic function接受2首或更多个参数:

int open(const char* file, int flag, ...); 

因此,函数的第三个参数获取与一个不确定的值初始化,如果没有提供任何值。如果仅提供2个参数,则不存在编译器错误。另一方面,向open调用始终提供第三个参数并不是错误。

+0

您自己引用的文件清楚地表明,第三个参数是_optional_。 – arkascha

+1

@arkascha真的吗? _标志中指定了'O_CREAT'或'O_TMPFILE'时必须提供此参数;如果既没有指定'O_CREAT'也没有'O_TMPFILE',那么模式将被忽略._ –

+0

啊,谢谢,我的坏。我把你的回答直接和绝对地表达出来,因为你没有在其中提出这样的评论。 – arkascha

0

创建的文件上的访问模式必须在open(2)调用中指定为第三个参数。由于C的工作方式,第三个参数(允许取决于第二个参数中使用的标志)使得调用variadic,编译器不检查是否提供了正确数量的参数。由于这个原因,如果你没有传递第三个参数,它不会被调用代码压入堆栈,但函数将使用第三个参数的位置。你有一个未定义的行为问题,最好的结果是得到一个错误的访问模式的新文件。如果open(2)例程修改了第三个参数,则可能会发生崩溃。

您提供的访问模式将最终被umask位修改,以获得创建文件的最终模式。

相关问题