メインコンテンツ

ファイル アクセス モードまたはステータスが不適切です

fopen または open グループの関数のアクセス モード引数が無効

説明

この欠陥は、fopen または open グループ内の関数を、無効なまたは互換性のないファイル アクセス モードで、ファイル作成フラグを引数として、またはファイル ステータス フラグを引数として使用した場合に発生します。たとえば、関数 open の場合、有効な例は次のとおりです。

  • 有効なアクセス モードには、O_RDONLYO_WRONLY および O_RDWR が含まれる。

  • 有効なファイル作成フラグには、O_CREATO_EXCLO_NOCTTY および O_TRUNC が含まれる。

  • 有効なファイル ステータス フラグには、O_APPENDO_ASYNCO_CLOEXECO_DIRECTO_DIRECTORYO_LARGEFILEO_NOATIMEO_NOFOLLOWO_NONBLOCKO_NDELAYO_SHLOCKO_EXLOCKO_FSYNCO_SYNC などが含まれる。

欠陥は次のような状態で発生します。

状態リスク修正方法

関数 fopen に、空であるか無効なアクセス モードが渡される。

ANSI® C 標準によると、fopen への有効なアクセス モードは次のとおり。

  • r,r+

  • w,w+

  • a,a+

  • rb, wb, ab

  • r+b, w+b, a+b

  • rb+, wb+, ab+

fopen では、無効なアクセス モードについて動作が未定義となる。

実装によっては、アクセス モードの次のような拡張が許可されている。

  • GNU®: rb+cmxe,ccs=utf

  • Visual C++®: a+t (ここで、t にはテキスト モードを指定)

ただし、アクセス モードの文字列は、有効なシーケンスのいずれかで始まらなければならない。

fopen に有効なアクセス モードを渡す。
ステータス フラグ O_APPEND が、O_WRONLY または O_RDWR のいずれかと組み合わされずに関数 open に渡される。

O_APPEND は、ファイルの末尾に新規の内容が追加されることを示す。しかし、O_WRONLY または O_RDWR がないとファイルへの書き込みはできない。

関数 open は、この論理エラーについては -1 を返さない。

O_APPEND|O_WRONLY または O_APPEND|O_RDWR をアクセス モードとして渡す。
ステータス フラグ O_APPEND および O_TRUNC がともに関数 open に渡される。

O_APPEND は、ファイルの末尾に新規の内容が追加されることを示す。しかし、O_TRUNC は、ファイルを打ち切ってゼロにすることを示す。したがって、この 2 つのモードは一緒に動作できない。

関数 open は、この論理エラーについては -1 を返さない。

意図することに応じて、2 つのモードのいずれかを渡す。
ステータス フラグ O_ASYNC が関数 open に渡される。 特定の実装では、モード O_ASYNC によって信号駆動の I/O 操作が有効にされない。代わりに、fcntl(pathname, F_SETFL, O_ASYNC); を使用する。

修正方法

修正方法は、関数および使用されるフラグによって異なります。上の表に記載されている修正と以下の修正付きのコード例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

すべて展開する

#include <stdio.h>

void func(void) {
    FILE *file = fopen("data.txt", "rw");
    if(file!=NULL) {
        fputs("new data",file);
        fclose(file);
    }
}

この例では、アクセス モード rw は無効です。r はファイルを読み取り用に開くことを示し、w は書き込み用に新規ファイルを作成することを示しますが、この 2 つのアクセス モードには互換性がないためです。

修正 — rw のいずれか一方をアクセス モードとして使用

1 つの修正方法として、意図することに応じたアクセス モードを使用します。

#include <stdio.h>

void func(void) {
    FILE *file = fopen("data.txt", "w");
    if(file!=NULL) {
        fputs("new data",file);
        fclose(file);
    }
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: オフ
コマンド ライン構文: BAD_FILE_ACCESS_MODE_STATUS
影響度: Medium

バージョン履歴

R2015b で導入