最大off64_tより大きいファイルを読み取るか見つける方法は?問題は、プロセスのアドレス空間がファイル/proc/.../as
として表現されるために発生します。巨大な64ビットプロセス用のスパースファイル。実際にはかなり大きいです。 Solaris x86-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でのみ機能しないようです。この問題を解決する方法はありますか?
答え1
Solaris x86-64には、サイズが2 63を超える非常に大きなファイルがあります。つまり、off64_t
ここではプロセスアドレス空間proc
(/proc/<pid>/as
。
次のファイルを処理します。
- などを使用しないでください
fopen
。fseek
(私がテストしたSolarisバージョンでは)「違法な」オフセットで混乱を引き起こすlibcストリームルーチンを信頼しないでください。 - 使用
open64
、read
。 求める:
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ソースコードを調べてこれらの変換を実行できることを知っていますが、AIXなどのプラットフォームで動作することを想定
psinfo
してはいけません。pr_argv
しかし、非常に大きなオフセットを渡すと、「ただ動作します」。