JPCERT コーディネーションセンター

FIO07-C. rewind() ではなく fseek() を使用する

FIO07-C. rewind() ではなく fseek() を使用する

C99 のセクション 7.19.9.5 は、rewind() 関数を以下のように定義している[ISO/IEC 9899:1999]。

rewind 関数は、stream が指すストリームに対応するファイル位置表示子を、そのファイルの始めに位置付ける。すなわち、そのストリームに対応するエラー表示子もクリアすることを除けば、
(void)fseek(stream, 0L, SEEK_SET)
と等価とする。

すなわち、処理が成功したかどうかを返り値から確認することができない。ストリームが正しく巻き戻されたことを確認するには rewind() ではなく fseek() を使用するべきである。

違反コード

このコード例は、rewind() を使用して、入力ストリームのファイル位置表示子を先頭に設定している。

char *file_name;
FILE *fp;

/* file_name を初期化 */

fp = fopen(file_name, "r");
if (fp == NULL) {
  /* オープンエラーの処理 */
}

/* データの読み取り */

rewind(fp);

/* 続行 */

しかし、rewind() が成功したかどうかを判断できない。

適合コード

以下の解決法は rewind() の代わりに fseek() を使用して、処理が成功したかどうかを確認している。

char *file_name;
FILE *fp;

/* file_name を初期化 */

fp = fopen(file_name, "r");
if (fp == NULL) {
  /* オープンエラーの処理 */
}

/* データの読み取り */

if (fseek(fp, 0L, SEEK_SET) != 0) {
  /* エラーの処理 */
}

/* 続行 */
リスク評価

rewind() を使用すると、ファイル位置表示子がファイルの先頭に戻されたかどうかを確認できないため、プログラムの間違った実行につながるおそれがある。

レコメンデーション 深刻度 可能性 修正コスト 優先度 レベル
FIO07-C P3 L3
自動検出

Compass/ROSE はこのレコメンデーションの違反を検出できる。

参考情報
翻訳元

これは以下のページを翻訳したものです。

FIO07-C. Prefer fseek() to rewind()

Top へ

Topへ
最新情報(RSSメーリングリストTwitter