#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);
}
}
#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工作正常。不同之处在于选项标记的位置。
答案 0 :(得分:4)
在我的计算机上,S_IWRITE
与O_EXCL
具有相同的值。该计划:
int main() {
printf("%x %x\n", S_IREAD, S_IWRITE);
printf("%x\n", O_EXCL);
return 0;
}
给出:
100 80
80
所以我猜测,指定标记S_IWRITE
和O_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
。