为什么open()使用错误的权限创建我的文件?

时间:2010-02-11 14:48:46

标签: c unix file-io

我正在尝试从文件中读取一些文字,并使用open()read()write()将其写入另一个文件。

这是我的open()文件到写入(我想创建一个新文件并写入其中):

fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC);

这是将文件权限设置为我根本无法理解的内容。这是ls -l

的输出
---------T 1 chaitanya chaitanya 0 2010-02-11 09:38 test-1

即使是读取权限也被锁定。我试着寻找这个,但找不到任何东西。 奇怪的是,write()仍然成功地将数据写入文件。

另外,如果我做'chmod 777 test-1',事情就会再次开始正常工作。

有人可以让我知道我在公开电话中哪里出错吗?

谢谢!

供您参考,我已粘贴以下完整程序:

#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;
}

7 个答案:

答案 0 :(得分:76)

open()接受第三个参数,即权限集,即

open(filename, O_RDWR|O_CREAT, 0666)

0666是八进制数,即6中的每一个对应于三个权限位

6 = rw

7 = rwx

这是一个典型的陷阱。编译器允许您保留权限参数,因为当您打开现有文件时,权限位没有意义。但是当您在创建文件时忘记参数时,您会获得一组随机权限,例如:你的情况是0000(---)。

答案 1 :(得分:9)

阅读http://linux.die.net/man/2/open,您似乎错过了开放的mode参数:

  O_CREAT在标志中时必须指定

模式,否则将被忽略。    参数模式指定在创建新文件时使用的权限。

答案 2 :(得分:8)

这个问题最近帮助了我,所以我想尽我所能来增加一些关于发生了什么的深度。就像之前所说的那样,你错过了open()的第三个参数。但是,您看到的权限不是随机的;他们来自堆栈。请查看以下代码段:

    asm("push $0");
    asm("push $0");
    asm("push $0");
    fd = open("base", O_RDWR|O_CREAT);

请注意以下结果:

    ----------. 1 user user 4 Feb 26 08:21 base

让我们将第一次推送更改为1,即执行权限:

    asm("push $1;push $0;push $0");
    fd = open("base", O_RDWR|O_CREAT);

我们得到:

    ---------x. 1 user user 4 Feb 26 08:25 base

将推送更改为4,即读取权限,并将其他两个值弄乱:

    asm("push $4;push $5;push $6");
    fd = open("base", O_RDWR|O_CREAT);

我们得到:

    -------r--. 1 user user 4 Feb 26 08:27 base

因此,我们可以看到从堆栈中弹出的第三个值(首先被推送)才是真正重要的。最后为了好玩,我们可以尝试5然后50,分别导致:

    -------r-x. 1 user user 4 Feb 26 08:27 base
    ----rw----. 1 user user 4 Feb 26 08:28 base

希望这会增加一些清晰度!

答案 3 :(得分:3)

实际上umask()仅过滤权限而不设置权限。典型的umask()值为0002(“不向世界提供写入权限”),如果open( "file", O_CREAT, 0777)中的模式值授予所有权限,则生成的文件将具有775 {1}}作为其权利。

答案 4 :(得分:1)

您可以在使用umask(0);系统调用之前调用open();系统调用,以便将选择权限设置为正确归档。

答案 5 :(得分:1)

与问题并不严格相关,但接受的答案可以使用这个澄清点:

rwx与其数值表示之间存在关系,可以通过将字母的存在视为二进制1来表示,并将其作为二进制0存在。

e.g。

rwx  <-->  111 (binary) <-->  7 (octal)

r--  <-->  100 (binary) <-->  4 (octal)

-wx  <-->  011 (binary) <-->  3 (octal) 

作为进一步的补充,您现在可以考虑chmod命令:

chmod 777 filename.extension - &gt; rwxrwxrwx权限

777 <--> 111 111 111 <--> rwx rwx rwx

或:chmod 654 filename.extension - &gt; RW-R-X-R -

654 <--> 110 101 100 <--> rw- r-x r--

希望这是有用的信息!

答案 6 :(得分:0)

这是一个旧线程,但我认为人们应该知道&#34; sys / stat.h&#34;图书馆。这包括一组用于设置权限位的符号常量。

例如:打开为用户启用读/写权限的文件

#include <fcntl.h>
#include <sys/stat.h>

open("Your/File/Path", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);

其中:

S_IWUSR // Sets the Users Write bit
S_IRUSR // Sets the Users Read bit

这个图书馆包含了很多其他内容,我不会在这里列出所有内容,但你可以全部阅读here

当然你可以输入八进制值来设置这些位,但是有些人可能会认为编码很糟糕。