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

Cha*_*nya 46 c unix file-io

我想从文件中读取一些文本并使用它写入到另一个open(),read()write().

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

fOut = open ("test-1", O_RDWR | O_CREAT | O_SYNC);
Run Code Online (Sandbox Code Playgroud)

这是将文件权限设置为我根本不理解的东西.这是输出ls -l:

---------T 1 chaitanya chaitanya 0 2010-02-11 09:38 test-1
Run Code Online (Sandbox Code Playgroud)

甚至读取权限也被锁定.我试着寻找这个,但找不到任何东西.奇怪的是,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;
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*ima 79

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

open(filename, O_RDWR|O_CREAT, 0666)
Run Code Online (Sandbox Code Playgroud)

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

6 = rw

7 = rwx

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

  • 我不明白最后一个参数是如何获得的,这不在手册页上? (6认同)
  • 为了完整性,八进制4 = r (2认同)
  • @Adam Liss:十六进制4 = 八进制4。八进制对于权限来说很方便,因为每组3位组成一个权限单位和一个八进制数字。0644 = 0x1A4,但八进制表示法比十六进制表示法更容易查看权限。(部分经验,但主要是适当的位分组)。 (2认同)
  • 0666通常是一个很好的设置,即使你不打算让"其他"能够写入它.umask通常设置为0022,这将删除除所有者之外的所有人的写入权限. (2认同)

Zei*_*ssS 9

阅读http://linux.die.net/man/2/open似乎你错过了modeopen 的参数:

当O_CREAT在标志中时,必须指定mode,否则忽略.参数模式指定在创建新文件时使用的权限.


Bil*_*lly 8

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

    asm("push $0");
    asm("push $0");
    asm("push $0");
    fd = open("base", O_RDWR|O_CREAT);
Run Code Online (Sandbox Code Playgroud)

请注意以下结果:

    ----------. 1 user user 4 Feb 26 08:21 base
Run Code Online (Sandbox Code Playgroud)

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

    asm("push $1;push $0;push $0");
    fd = open("base", O_RDWR|O_CREAT);
Run Code Online (Sandbox Code Playgroud)

我们得到:

    ---------x. 1 user user 4 Feb 26 08:25 base
Run Code Online (Sandbox Code Playgroud)

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

    asm("push $4;push $5;push $6");
    fd = open("base", O_RDWR|O_CREAT);
Run Code Online (Sandbox Code Playgroud)

我们得到:

    -------r--. 1 user user 4 Feb 26 08:27 base
Run Code Online (Sandbox Code Playgroud)

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

    -------r-x. 1 user user 4 Feb 26 08:27 base
    ----rw----. 1 user user 4 Feb 26 08:28 base
Run Code Online (Sandbox Code Playgroud)

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


小智 5

实际上umask()只过滤权限而不设置它们。典型umask()值是0002(“不要放弃对世界的写权限”),如果您的模式值open( "file", O_CREAT, 0777)授予所有权限,则生成的文件将775作为其权限。