6

次のコードが与えられた場合 (「helloworld」ファイルに「helloworld」を書き込み、テキストを読み取ることになっています):

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

#define FNAME "helloworld"

int main(){ 
    int filedes, nbytes;
    char buf[128];

    /* Creates a file */
    if((filedes=open(FNAME, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, 
        S_IRUSR | S_IWUSR)) == -1){
            write(2, "Error1\n", 7);
    }

    /* Writes hello world to file */
    if(write(filedes, FNAME, 10) != 10)
        write(2, "Error2\n", 7);

    /* Close file */
    close(filedes);

    if((filedes = open(FNAME, O_RDONLY))==-1)
        write(2, "Error3\n", 7);

    /* Prints file contents on screen */    
    if((nbytes=read(filedes, buf, 128)) == -1)
        write(2, "Error4\n", 7);

    if(write(1, buf, nbytes) != nbytes)
        write(2, "Error5\n", 7);

    /* Close file after read */
    close(filedes); 

    return (0);
}

プログラムを初めて実行すると、出力は次のようになります。

helloworld

その後、プログラムを実行するたびに、出力は次のようになります。

Error1
Error2
helloworld

O_APPEND ファイルを指定したため、テキストが追加されない理由がわかりません。O_CREAT を入れたからでしょうか。ファイルが既に作成されている場合、O_CREAT は無視されるべきではありませんか?

4

1 に答える 1

12

O_EXCLファイルの作成を強制します。ファイルが既に存在する場合、呼び出しは失敗します。

これは、3 番目のパラメーターで渡された特定のアクセス許可を使用して、ファイルを作成する必要があることを確認するために使用されます。つまり、次のオプションがあります。

  • O_CREAT: ファイルがまだ存在しない場合は、指定された権限でファイルを作成します。ファイルが存在する場合は開かれ、権限は無視されます。
  • O_CREAT | O_EXCL: ファイルがまだ存在しない場合は、指定された権限でファイルを作成します。ファイルが存在する場合、失敗します。これは、ロックファイルを作成し、ファイルへの排他的アクセスを保証するために役立ちます (そのファイルを使用するすべてのプログラムが同じプロトコルに従う限り)。
  • O_CREAT | O_TRUNC: ファイルがまだ存在しない場合は、指定された権限でファイルを作成します。それ以外の場合は、ファイルを 0 バイトに切り捨てます。これは、「新しい空のファイルを作成する」と考えたときに期待される効果以上のものです。それでも、既存のファイルに既に存在するアクセス許可が保持されます。

マニュアルページからの詳細情報:

O_EXCL

O_CREAT と共に使用すると、ファイルが既に存在する場合はエラーになり、open() は失敗します。このコンテキストでは、シンボリック リンクがどこを指しているかに関係なく存在します。O_EXCL は NFS ファイル システムでは機能しません。ロックタスクを実行するためにそれに依存するプログラムには、競合状態が含まれます。lockfile を使用してアトミック ファイル ロックを実行するための解決策は、同じファイル システム上に一意のファイルを作成し (たとえば、ホスト名と pid を組み込む)、link(2) を使用してロックファイルへのリンクを作成することです。link() が 0 を返す場合、ロックは成功です。それ以外の場合は、一意のファイルで stat(2) を使用して、リンク数が 2 に増加したかどうかを確認します。この場合、ロックも成功しています。

于 2010-04-03T20:00:55.767 に答える