C语言 为什么 open() 使用错误的权限创建我的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2245193/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does open() create my file with the wrong permissions?
提问by Chaitanya
I am trying to read some text from a file and write it to another using open(), read()and write().
我正在尝试从文件中读取一些文本open(),read()然后使用,和将其写入另一个文件write()。
This is my open()for the file-to-write-to (I want to create a new file and write into it):
这是我open()的文件写入(我想创建一个新文件并写入其中):
fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC);
This is setting file-permissions to something I don't understand at all. This is the output of ls -l:
这是将文件权限设置为我根本不了解的内容。这是输出ls -l:
---------T 1 chaitanya chaitanya 0 2010-02-11 09:38 test-1
Even the read permission is locked. I tried searching for this, but could not find ANYTHING.
Strangely, write()still successfully writes data to the file.
甚至读取权限也被锁定。我试图搜索这个,但找不到任何东西。奇怪的是,write()仍然成功地将数据写入文件。
Also, if I do a 'chmod 777 test-1', things start working properly again.
另外,如果我执行'chmod 777 test-1',一切又会开始正常工作。
Could someone please let me know where I am going wrong in my open call?
有人可以让我知道我在公开电话中出错的地方吗?
Thanks!
谢谢!
For your reference, I have pasted the complete program below:
为了您的参考,我已经粘贴了下面的完整程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main () {
char buffer[512], ch;
int fIn, fOut, i;
ssize_t bytes;
FILE *fp = NULL;
//open a file
fIn = open ("test", O_RDONLY);
if (fIn == -1) {
printf("\nfailed to open file.");
return 1;
}
//read from file
bytes = read (fIn, buffer, sizeof(buffer));
//and close it
close (fIn);
printf("\nSuccessfully read %d bytes.\n", bytes);
//Create a new file
fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC);
printf("\nThese are the permissions for test-1\n");
fflush(stdout);
system("ls -l test-1");
//write to it and close it.
write (fOut, buffer, bytes);
close (fOut);
//write is somehow locking even the read permission to the file. Change it.
system("chmod 777 test-1");
fp = fopen ("test-1", "r");
if (fp == NULL) {
printf("\nCan't open test-1");
return 1;
}
while (1)
{
ch = fgetc(fp);
if (ch == EOF)
break;
printf("\n%c", ch);
}
fclose (fp);
return 0;
}
回答by Antti Huima
open() takes a third argument which is the set of permissions, i.e.
open() 接受第三个参数,即权限集,即
open(filename, O_RDWR|O_CREAT, 0666)
0666 is an octal number, i.e. every one of the 6's corresponds to three permission bits
0666 是一个八进制数,即每一个 6 位对应三个权限位
6 = rw
6 = rw
7 = rwx
7 = rwx
first three bits for owner permission, next three bits for group permission and next is for the world the first digit - represents that is file or directory. (0 - file, d - directory) here we used 0 means file
前三位为所有者权限,接下来的三位为组权限,接下来是世界的第一位数字 - 代表文件或目录。(0 - 文件,d - 目录)这里我们使用 0 表示文件
It's a typical pitfall. The compiler allows you to leave the permission argument away because when you open an existing file the permission bits don't make sense. But when you forget the argument when you create a file, you get a random set of permissions, e.g. 0000 in your case (---).
这是一个典型的陷阱。编译器允许您保留权限参数,因为当您打开现有文件时,权限位没有意义。但是当您在创建文件时忘记参数时,您将获得一组随机权限,例如在您的情况下为 0000 (---)。
回答by ZeissS
Reading http://linux.die.net/man/2/openit seems you missed the modeparameter for open:
阅读http://linux.die.net/man/2/open似乎您错过了modeopen 参数:
mode must be specified when O_CREAT is in the flags, and is ignored otherwise. The argument mode specifies the permissions to use in case a new file is created.
当 O_CREAT 在标志中时必须指定模式,否则将被忽略。参数 mode 指定在创建新文件时使用的权限。
回答by Billy
This question recently helped me out, so I wanted to do my part to add a bit more depth as to what's going on. Like it was stated before, you were missing the third argument to open(). However, the permissions you see aren't random; they're coming from the stack. Look at the following code snippet:
这个问题最近帮助了我,所以我想尽自己的一份力量来更深入地了解正在发生的事情。就像之前所说的那样,您错过了open(). 但是,您看到的权限不是随机的;他们来自堆栈。看下面的代码片段:
asm("push ----------. 1 user user 4 Feb 26 08:21 base
");
asm("push asm("push ;push ---------x. 1 user user 4 Feb 26 08:25 base
;push asm("push ;push ;push ");
fd = open("base", O_RDWR|O_CREAT);
");
fd = open("base", O_RDWR|O_CREAT);
");
asm("push -------r--. 1 user user 4 Feb 26 08:27 base
");
fd = open("base", O_RDWR|O_CREAT);
Note the following result:
请注意以下结果:
-------r-x. 1 user user 4 Feb 26 08:27 base
----rw----. 1 user user 4 Feb 26 08:28 base
Let's change the first push to 1, i.e. execute permission:
让我们将第一次推送更改为 1,即执行权限:
rwx <--> 111 (binary) <--> 7 (octal)
r-- <--> 100 (binary) <--> 4 (octal)
-wx <--> 011 (binary) <--> 3 (octal)
and we get:
我们得到:
777 <--> 111 111 111 <--> rwx rwx rwx
Change the push to 4, i.e. read permission, and mess with the other two values:
把push改成4,即读权限,把另外两个值弄乱:
654 <--> 110 101 100 <--> rw- r-x r--
and we get:
我们得到:
#include <fcntl.h>
#include <sys/stat.h>
open("Your/File/Path", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);
Thus we can see the third value popped off the stack (first pushed) is what really matters. Finally for fun we can try 5 and then 50, which respectively result in:
因此,我们可以看到从堆栈中弹出的第三个值(首先压入)才是真正重要的。最后为了好玩,我们可以尝试 5 和 50,它们分别导致:
S_IWUSR // Sets the Users Write bit
S_IRUSR // Sets the Users Read bit
Hope this adds some clarity!
希望这会增加一些清晰度!
回答by rgt
Actually umask()only filters permissions and does not set them. The typical umask()value is 0002("don't give away write permission to the world") and if your mode value in the open( "file", O_CREAT, 0777)gave all permissions, the resulting file would have 775as its permssions.
实际上umask()只过滤权限而不设置它们。典型umask()值是0002(“不要放弃对世界的写权限”),如果您的模式值open( "file", O_CREAT, 0777)授予所有权限,则生成的文件将775作为其权限。
回答by Abdo
you can call umask(0);system call before using open();system call to set your choices permissions to file correctly.
您可以umask(0);在使用系统调用之前调用open();系统调用来设置您的选择权限以正确归档。
回答by Evan
Not strictly relevant to the question, but the accepted answer could use this clarifying point:
与问题并不严格相关,但接受的答案可以使用以下澄清点:
There is a relationship between rwx and its numerical representation that can be seen by treating the presence of a letter as a binary 1, and its absence as a binary 0.
rwx 和它的数字表示之间存在一种关系,可以通过将一个字母的存在视为二进制 1,将其不存在视为二进制 0 来看出。
e.g.
例如
##代码##As a further addendum, you may now consider the chmod command:
作为进一步的附录,您现在可以考虑 chmod 命令:
chmod 777 filename.extension --> rwxrwxrwx permissions
chmod 777 filename.extension --> rwxrwxrwx 权限
##代码##or: chmod 654 filename.extension --> rw-r-x-r--
或:chmod 654 文件名.扩展名--> rw-rxr--
##代码##Hope this is informative!
希望这是信息性的!
回答by Levi Meston
This is kind of an old thread, but I think people should be aware of the "sys/stat.h" library. This includes a bunch of symbolic constants for setting permission bits.
这是一个旧线程,但我认为人们应该知道“sys/stat.h”库。这包括一组用于设置权限位的符号常量。
For example: To open a file with Read/Write permissions enabled for the user
例如:打开一个为用户启用读/写权限的文件
##代码##where:
在哪里:
##代码##This library includes a bunch of others, I won't list them all here but you can read up on it all here.
这个库包含了一堆别人的,我就不一一列举了所有在这里,但你都可以阅读它在这里。
Of course you can put in the octal values to set these bits, however some may argue that it is poor coding practice.
当然,您可以输入八进制值来设置这些位,但是有些人可能会认为这是糟糕的编码实践。

