web-dev-qa-db-ja.com

open()が間違ったパーミッションでファイルを作成するのはなぜですか?

open()read()、およびwrite()を使用して、ファイルからテキストを読み取って別のテキストに書き込もうとしています。

これは、file-to-write-toの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;
}
_
45
Chaitanya

open()は、許可のセットである3番目の引数を取ります。

open(filename, O_RDWR|O_CREAT, 0666)

0666は8進数です。つまり、6のすべてが3つの許可ビットに対応します。

6 = rw

7 = rwx

それは典型的な落とし穴です。コンパイラでは、既存のファイルを開くときにアクセス許可ビットが意味をなさないため、アクセス許可引数をそのままにしておくことができます。ただし、ファイルを作成するときに引数を忘れると、ランダムなアクセス許可セットが取得されます。あなたの場合は0000(---)。

76
Antti Huima

http://linux.die.net/man/2/open を読むと、openのmodeパラメーターを逃したようです:

o_CREATがフラグ内にある場合、modeを指定する必要があり、そうでない場合は無視されます。引数モードは、新しいファイルが作成された場合に使用する許可を指定します。

9
ZeissS

この質問は最近私を助けてくれたので、何が起こっているかについてもう少し深みを加えるために自分の役割を果たしたかったのです。前に述べたように、open()の3番目の引数がありませんでした。ただし、表示されるアクセス許可はランダムではありません。彼らはスタックから来ています。次のコードスニペットを見てください。

    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に変更します。つまり、読み取りアクセス許可を変更し、他の2つの値を台無しにします。

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

そして私達は得る:

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

したがって、スタックからポップされた3番目の値(最初にプッシュされた値)が本当に重要であることがわかります。最後に、楽しみのために5を試してから50を試してみてください。

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

これがいくつかの明確さを追加することを願っています!

8
Billy

実際にumask()は許可のみをフィルターし、それらを設定しません。典型的なumask()値は_0002_(「書き込み許可を世界に与えないでください」)およびopen( "file", O_CREAT, 0777)のモード値がすべての許可を与えた場合、結果はファイルのパーミションは_775_になります。

3
rgt

質問に厳密には関連していませんが、受け入れられた答えはこの明確なポイントを使用できます:

Rwxとその数値表現の間には関係があり、文字の存在をバイナリ1として、その不在をバイナリ0として扱うことで確認できます。

例えば.

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

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

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

さらなる補足として、chmodコマンドを検討することができます。

chmod 777 filename.extension-> rwxrwxrwxパーミッション

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

または:chmod 654 filename.extension-> rw-r-x-r--

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

これが参考になることを願っています!

1
Evan

umask(0);システムコールを使用する前にopen();システムコールを呼び出して、ファイルへの選択権限を正しく設定できます。

1
Abdo

これは一種の古いスレッドですが、人々は「sys/stat.h」ライブラリに注意する必要があると思います。これには、許可ビットを設定するための一連の記号定数が含まれます。

例:ユーザーに対して読み取り/書き込み権限を有効にしてファイルを開くには

#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

もちろん、これらのビットを設定するために8進数の値を入力することもできますが、コーディングの習慣が悪いと主張する人もいるかもしれません。

0
Levi Meston