2012-03-06 11 views
0

私は、システムコールを作るカーネル空間から返された構造体をユーザ空間にコピーすることは不可欠ですか?

struct hostent * gethostbyaddr (const char *addr, int len, int family);

を言うと、それはstruct*を返した場合、私が代わりに直接ポインタを使用してのどこかにI「自分」に構造体をコピーする必要がありますか?

+0

典型的な実装は、スレッドローカルストレージへのポインタを返します。追加の電話をかけると、詳細なコピーを作成する方がよいでしょう。スレッドを使用していて、TLSが使用されているかどうかわからない場合は、ロックを使用することをお勧めします。 –

+0

'gethostbyaddr'はシステムコールではなく、ライブラリルーチンです。システムコールであっても、カーネル空間にポインタを戻すことはありません。 –

答えて

3

gethostbyaddrreadsのドキュメント(ノートセクションを参照):

関数のgethostbyname()とのgethostbyaddr()は、後の呼び出しによって上書きされるかもしれない静的データへのポインタ を返すことができます。 struct hostentの をコピーするだけでは、ポインタが含まれているため十分ではありません。深い コピーが必要です。

これは、後でgethostbyaddrを呼び出すときに上書きされないようにするには、構造体をコピーする必要があることを意味します。

gethostbyaddrは時代遅れですので、実際にはgetaddrinfoを使用することを検討する必要があります。 getaddrinfoでは、結果のメモリを自分で割り当てる必要があるため、この質問はしません。

+0

'構造hostentをコピーするだけでは十分ではありません.' - 返された構造体をコピーできないのではないのですか? 'getaddrinfo'が正しい勧告です。 – ugoren

+0

@ugoren:構造体に別の構造体へのポインタが含まれているため、浅いコピーを使用できないため、ディープコピーを使用する必要があります。 –

+0

ディープコピーはあまり明確に定義されていません。それはコピーしたい構造に依存します。 「構造体をコピーする」と書くと、それは浅いコピーを意味すると思います。 – ugoren

0

いいえ、ポインタを直接使用できます。

(それについて考えてみましょう:メモリにアクセスできない、またはアクセスするのが安全でない場合はコピーできません。逆も同様です。コピーできる場合は、その場所でも使用できます)。

+0

しかし、OSはどのようにこのメモリを消去するのかを知っていますか?私はそのメモリから読んでいる間、OSがそれをリフレッシュすることを恐れる。 –

+1

@can:プロセスが終了すると、OSはメモリに触れるだけである。 'gethostbyaddr'によって返されたポインタは、カーネル空間へのポインタではありません。 –

+1

これは機能ごとに異なります。私のBSDでは、 'gethostbyaddr'はスレッドローカルストレージを使い、このスレッドの後続の呼び出しでメモリが上書きされるだけだと述べています。他の実装では、 'gethostbyaddr'はスレッドに安全でないポインタを静的データに返すことがあります。他の機能は異なる動作をすることがあります(たとえば、メモリを解放する必要があります)。それぞれのドキュメントの説明を読む必要があります。 – hamstergene

関連する問題