web-dev-qa-db-ja.com

Solarisでmax(off64_t)より大きいファイル(例: "/ proc /../as")

最大off64_tよりも大きいファイルを読み取ったりシークしたりするにはどうすればよいですか?この問題は、プロセスのアドレス空間が/proc/.../asファイルで表されるために発生します。これは、64ビットプロセスの巨大スパースファイルです。これは非常に大きいです。Solarisx86-64のサンプルプロセスでは、argvのアドレスは0xFFFFFD7FFFxxxxxxです。つまり、アドレス空間の最上部が使用されます。ポインタは署名されていませんが、off64_tは署名されているため、アドレス空間ファイルの上半分の何にも到達できません。

これは明らかにアドレス空間のレイアウトに依存します。 32ビットシステムでは、これは問題ではありません(longオフセットは十分な大きさではありませんが、off64_tは簡単に機能します)。Linuxのx86-64(たとえば)では、プロセスの先頭は0x7fffxxxxxxxx(48ビット)であるため、off64_tはプロセスのアドレス空間内のすべてを参照できます。

したがって、x86-64上のSolarisが、50ビットで十分な場合に、64ビットのアドレス空間全体を使用しているように見えるのは残念です。 psinfo_t.pr_argvを使用したSunの例は、SPARCおよびx86を除いては機能しないようです。この問題を回避する方法はありますか?

6
Nicholas Wilson

Solaris x86-64には、サイズが2を超える非常に大きなファイルがいくつかあります。63、つまり、off64_tで表現できる最大サイズ。これには、proc/proc/<pid>/as)内のプロセスのアドレス空間を表すファイルが含まれます。

これらのファイルを処理するには:

  1. fopenfseekなどを使用しないでください。(テストしたSolarisのバージョンで)「不正な」オフセットをひどく壊すlibcストリームルーチンを信頼しないでください。
  2. open64readを使用します。
  3. 捜すために:

    static off64_t lseeku64(int file, uint64_t offset /* eg from pr_argv */)
    {
    #ifndef __Sun
      if (offset > 0x7FFFFFFFFFFFFFFFllu) return -1;
    #endif
      return lseek64(file, offset, SEEK_SET);
    }
    

    つまり、Solarisでは、OpenSolarisソースを検査することでこのキャストを実行できることがわかっていますが、psinfoおよびpr_argvを備えた他のプラットフォーム(AIXなど)で機能すると想定することは避けてください。

    しかし、非常に大きなオフセットを渡すと、すべて「正しく機能」します。

0
Nicholas Wilson