open()系统调用的工作方式不同

时间:2013-11-21 01:56:29

标签: c

计划1

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
   int fd1, fd2;
   fd1 = open("dup1.txt", O_RDWR | O_CREAT| S_IREAD | S_IWRITE);
   printf("\nOriginal fd = %d", fd1);
   if(fd1 == -1){
     printf("\nFATAL Error\n");
     exit(1);
   }
}

计划2

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
   int fd1, fd2;
   fd1 = open("dup1.txt", O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
   printf("\nOriginal fd = %d", fd1);
   if(fd1 == -1){
     printf("\nFATAL Error\n");
     exit(1);
   }
}

如果文件已经存在,则program1为fd返回-1(如果文件已经存在则工作正常),但第一个下面的program2工作正常。不同之处在于选项标记的位置。

3 个答案:

答案 0 :(得分:4)

在我的计算机上,S_IWRITEO_EXCL具有相同的值。该计划:

int main() { 
    printf("%x %x\n", S_IREAD, S_IWRITE);
    printf("%x\n", O_EXCL);

    return 0; 
} 

给出:

100 80
80

所以我猜测,指定标记S_IWRITEO_CREAT现在与O_CREAT | O_EXCL具有相同的效果,这会导致open失败如果文件已经存在。

但是,我认为您应该在正确使用其参数的情况下调用系统调用。

答案 1 :(得分:1)

使用O_CREAT时,open()接受三个参数,第三个参数是要创建的文件的权限:

fd1 = open("dup1.txt", O_RDWR | O_CREAT, 0644);

权限(S_I*标志)永远不会在options(second)参数(使用O_*标志)中指定,反之亦然。从理论上讲,符号名称比八进制文字更便携,但IMNSHO八进制文字更容易理解。您可以使用您喜欢的任何权限,但除非您正在创建可执行程序,否则您可能不应该为任何人设置x位,出于安全考虑,您应该考虑不授予组或公共写入权限(允许当用户认为合适时,umask()会覆盖组和公共读取访问。经典(在以前的安全性不太重要的时候),默认情况下,文件的权限通常为0666。

答案 2 :(得分:1)

可以使用2或3个参数调用open系统调用。

这两个电话:

fd1 = open("dup1.txt", O_RDWR | O_CREAT| S_IREAD | S_IWRITE);

fd1 = open("dup1.txt", O_RDWR | O_CREAT, S_IREAD | S_IWRITE);

完全不同;第一个传递第二个参数等于O_RDWR | O_CREAT| S_IREAD | S_IWRITE,第二个参数传递等于O_RDWR | O_CREAT的第二个参数,第三个参数传递等于S_IREAD | S_IWRITE

第二个参数应始终是一个或多个标志的“或”,其名称以O_开头。

当且仅当第二个参数包含O_CREAT标志时,您需要传递第二个参数,该参数应该是一个或多个标志的按位“或”,其名称以S_开头,或指定权限的0640之类的八进制数。

您的第一个电话不正确;你不应该在第二个参数中传递S_*个标志,如果第二个参数包含O_CREAT,你需要第三个参数。

这种传递两个或三个参数的能力有点奇怪。 Linux手册页文档open如下:

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

这可以说是不正确的(C没有这样的函数重载)。 POSIX描述如下:

int open(const char *path, int oflag, ...);

使其成为可变参数函数,类似于printf