私は数週間、システムに依存しない必要がある 20 年のコードを更新するという問題に対処してきました (Linux と Windows の両方で動作します)。これには、Time-of-Check、Time-of-Use (TOCTOU) の問題が含まれます。ここにスレッドを立てましたが、あまりうまくいきませんでした。しばらく反芻し、問題を深く調べた後、私の質問が少しよく理解できたと思います。もう少し上手に聞いてもいいのかな…
私が読んだことから、コードはファイルが存在するかどうかを確認し、アクセス可能であればファイルを開き、いくつかの操作を行い、最後にファイルを閉じる必要があります。これを行う最善の方法は、 へlstat()
の呼び出し、 へfopen()
の呼び出し、fstat()
(TOCTOU を除外するための) への呼び出し、そして操作とファイルのクローズです。
ただし、相互互換性のために使用すべきではないのとほぼ同じように、システムにとらわれないプログラムでの使用を除外し、C標準で定義されているのではなく、POSIXで定義されているlstat()
と信じるようになりました。これをどのように実装しますか?fstat()
open()
私の最初の投稿を見ると、20 年前の開発者が C プリプロセッサを使用して相互互換性のある部分にコードを切り分けていたことがわかりますが、それを行ったとしても、何を置き換えるlstat()
かfstat()
(彼らのWindows の対応物)。
編集: この投稿に短縮コードを追加しました。不明な点がある場合は、元の投稿に移動してください
#ifdef WIN32
struct _stat buf;
#else
struct stat buf;
#endif //WIN32
FILE *fp;
char data[2560];
// Make sure file exists and is readable
#ifdef WIN32
if (_access(file.c_str(), R_OK) == -1) {
#else
if (access(file.c_str(), R_OK) == -1) {
#endif //WIN32
char message[2560];
sprintf(message, "File '%s' Not Found or Not Readable", file.c_str());
throw message;
}
// Get the file status information
#ifdef WIN32
if (_stat(file.c_str(), &buf) != 0) {
#else
if (stat(file.c_str(), &buf) != 0) {
#endif //WIN32
char message[2560];
sprintf(message, "File '%s' No Status Available", file.c_str());
throw message;
}
// Open the file for reading
fp = fopen(file.c_str(), "r");
if (fp == NULL) {
char message[2560];
sprintf(message, "File '%s' Cound Not be Opened", file.c_str());
throw message;
}
// Read the file
MvString s, ss;
while (fgets(data, sizeof(data), fp) != (char *)0) {
s = data;
s.trimBoth();
if (s.compare( 0, 5, "GROUP" ) == 0) {
//size_t t = s.find_last_of( ":" );
size_t t = s.find( ":" );
if (t != string::npos) {
ss = s.substr( t+1 ).c_str();
ss.trimBoth();
ss = ss.substr( 1, ss.length() - 3 ).c_str();
group_list.push_back( ss );
}
}
}
// Close the file
fclose(fp);
}