1

次のコードが正しく機能するのはなぜですか?

void continuous_mmap (void)
{
 struct stat buf;
 int fd = open("file_one", O_RDONLY), i;
 char *contents;

 fstat(fd, &buf);
 contents = mmap(NULL, buf.st_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
 close (fd);
 mprotect(contents, buf.st_size, PROT_READ);
 for (i = 0; i < 15; i++) {
  printf ("%s\n", contents);
  sleep (1);
 }
 munmap(contents, buf.st_size);
}

まず、追加された場合でも、ファイルは同期されたままになります (ファイルを外部で編集および保存すると、更新されたコンテンツが自動的に印刷されます)。マッピングしたバイト数 (初期ファイル サイズ) を超えてコードがセグメンテーション違反なしでアクセスできるようにするにはどうすればよいですか? mmap常に長さをシステムページサイズに切り上げているためですか? もしそうなら、この動作は一般的なシステムに依存している可能性があります ( man ページPOSIXでそのような要件を見つけることができませんでした)。mmap

第二に、どのようにしてテキストに ? が自動的に追加され'0'ますか? マップされていないバイトが自動的にゼロになるためですか? この動作は依存できますか?

4

3 に答える 3

2

はい、標準は言う

システムは、オブジェクトの最後にある部分ページを常にゼロで埋める必要があります。さらに、システムは、オブジェクトの最後のページの変更された部分のうち、オブジェクトの終わりを超えた部分を決して書き出さないものとします。

  • もしそうなら、この動作は一般的に POSIX システムに依存していますか (mmap のマニュアル ページでそのような要件を見つけることができませんでした)。

いいえ、私はそうしません。すべての実装が準拠しているわけではありません。私は少なくとも 1 つの完全に壊れた実装を見たことがあります。

mmapこれには呼び出しのこの機能を使用するのではなくftruncate、必要に応じてファイルを長くする必要があります。

于 2010-11-11T08:02:42.127 に答える
1

POSIX は、重要なページ サイズを義務付けさえしません。理論的には、実装の「ページ」サイズは 1 バイトです。同様に、ファイルサイズを超えてページの残りからゼロを読み取ることは指定されていないようです。ここで切り捨てられた古いファイルの内容をリークする壊れた実装がいくつかあることは想像できますが、そのような実装を現実の世界では無関係にする重大なセキュリティ/プライバシー違反だと考えます. もちろん、彼らはスペースを埋めることができ0xDEADBEEF、それからあなたは運が悪いでしょう.

ゼロ パディングを想定できたとしても (これはおそらく、ほとんどの実際のオペレーティング システムに当てはまります)、使用しないように注意します。ファイルがたまたまシステム ページ サイズの正確な倍数である場合はどうなりますか? 突然コードが最後まで読んでクラッシュしたり、(おそらくもっと悪いことに) たまたまファイルのマッピングに隣接してマップされた無関係なページから読み取ったりします。システム ページ サイズの正確な倍数のテキスト ファイルが存在する可能性は非常に低いため、これは非常に厄介なバグであり、おそらく見つけられないでしょう。

于 2010-11-11T07:49:25.460 に答える
0

ファイルがマップされているにもかかわらず、ファイルへの外部更新が表示されるMAP_PRIVATE理由は、マッピングに書き込んでおらず、システムがファイル ページのプライベート コピーをまだ提供していないためです。この動作は許可されていますが、必須ではありません。

contents[0]ループの前にアプリケーションを変更した場合、外部の変更は認識されません。

于 2010-11-11T10:41:16.350 に答える