2

/etc/netconfig私はオラクルプロセスを追跡し、最初にファイルをファイルハンドルとして開き、次にパラメーターを使用して呼び出す11ことで複製し、次に元のファイルハンドルを複製することを発見しました。後でファイルハンドルを使用して読み取ります。では、ファイル ハンドルを複製するポイントは何でしょうか。元のファイル ハンドルで作業しないのはなぜですか?256fcntlF_DUPFDclose11256

12931:   0.0006 open("/etc/netconfig", O_RDONLY|O_LARGEFILE)    = 11
12931:   0.0002 fcntl(11, F_DUPFD, 0x00000100)                  = 256
12931:   0.0001 close(11)                                       = 0
12931:   0.0002 read(256, " # p r a g m a   i d e n".., 1024)   = 1024
12931:   0.0003 read(256, " t s           t p i _ c".., 1024)   = 215
12931:   0.0002 read(256, 0x106957054, 1024)                    = 0
12931:   0.0001 lseek(256, 0, SEEK_SET)                         = 0
12931:   0.0002 read(256, " # p r a g m a   i d e n".., 1024)   = 1024
12931:   0.0003 read(256, " t s           t p i _ c".., 1024)   = 215
12931:   0.0003 read(256, 0x106957054, 1024)                    = 0
12931:   0.0001 close(256)                                      = 0
4

3 に答える 3

6

Solaris などの一部のシステムでは、構造体の実装で int ではなく 8 ビット整数が使用FILEされるため、標準 I/O はファイル記述子 0 ~ 255 でのみ機能します。FILEプログラムが多くのファイル記述子を使用する場合、 を使用してファイル記述子を予約すると便利ですfnctl(fd, F_DUPFD, 256)。そうしないと、 のように機能fopen()し、256 個のファイルを開いていると失敗しますfreopen()fdopen()

于 2011-01-07T15:02:10.617 に答える
5

余談ですが、これらはファイルハンドルではなくファイル記述子です。後者は、およびその兄弟で使用される C の機能ですが、記述子は、その他で使用するためにより UNIX 的です。fopenopen

面白い。頭に浮かぶ唯一の理由は、ファイル記述子を 256 にする必要がある他のコードがあるということです。その奇妙な理由を知っているのは Oracle だけだと思います。いずれにせよ、256 を取得する保証はありません。その数値以上の最初に使用可能なファイル記述子を取得します。


少し調べてみると (頭のてっぺんから UNIX の内部についてすべてを知っているわけではありません)、ファイル位置やアクセス モードなどの重複した記述子のグループに属する属性があります。GNULib の close-on-exec フラグのように、複製されている場合でも、単一のファイル記述子に属する他の属性があります。

複製を(dupdup2またはあなたの のいずれかでfcntl)行うと、1つが異なるファイル記述子属性を持つ2つの記述子を作成する方法になる可能性がありますが、最初の記述子が閉じられているため、あなたの質問ではそうではありません。あなたが言うように、低記述子を使用しないのはなぜですか?

興味深いことに、Google でを検索すると、 が失敗しnetconfig f_dupfdた同様のトレースがfcntl表示され、低い記述子でそのファイルを読み続けているため、この問題についての私の考えは、これは低いファイル記述子を可能な限り保持する試みであるということです。例えば:

4327:   open("/etc/netconfig", O_RDONLY|O_LARGEFILE)    = 4
4327:   fcntl(4, F_DUPFD, 0x00000100)                   Err#22 EINVAL
4327:   read(4, " # p r a g m a   i d e n".., 1024)     = 1024
4327:   read(4, " t s           t p i _ c".., 1024)     = 215
4327:   read(4, 0x00296B80, 1024)                       = 0
4327:   lseek(4, 0, SEEK_SET)                           = 0
4327:   read(4, " # p r a g m a   i d e n".., 1024)     = 1024
4327:   read(4, " t s           t p i _ c".., 1024)     = 215
4327:   read(4, 0x00296B80, 1024)                       = 0
4327:   close(4)                                        = 0

おそらく、ソフトウェアには、制限されたファイル記述子のバイト配列がどこかにあるため、他のファイルを255制限を超えて移動しようとします。

しかし、実際には、それは私の推測にすぎません (ただし、比較的知的な推測だと思いたいのですが)。また、これを行っているのは Oracle 自体ではない可能性があることに注意してください。netconfig は多くの場所で使用されているため、特に前述の Web ヒットのほとんどが Oracle 固有 ( など) ではなかったという事実に照らして、それを行う基本的なライブラリである可能性がありftpますremsh

于 2010-04-12T03:47:10.197 に答える