私は、システムコールを作るカーネル空間から返された構造体をユーザ空間にコピーすることは不可欠ですか?
struct hostent * gethostbyaddr (const char *addr, int len, int family);
を言うと、それはstruct*
を返した場合、私が代わりに直接ポインタを使用してのどこかにI「自分」に構造体をコピーする必要がありますか?
私は、システムコールを作るカーネル空間から返された構造体をユーザ空間にコピーすることは不可欠ですか?
struct hostent * gethostbyaddr (const char *addr, int len, int family);
を言うと、それはstruct*
を返した場合、私が代わりに直接ポインタを使用してのどこかにI「自分」に構造体をコピーする必要がありますか?
gethostbyaddr
readsのドキュメント(ノートセクションを参照):
関数のgethostbyname()とのgethostbyaddr()は、後の呼び出しによって上書きされるかもしれない静的データへのポインタ を返すことができます。 struct hostentの をコピーするだけでは、ポインタが含まれているため十分ではありません。深い コピーが必要です。
これは、後でgethostbyaddr
を呼び出すときに上書きされないようにするには、構造体をコピーする必要があることを意味します。
gethostbyaddr
は時代遅れですので、実際にはgetaddrinfo
を使用することを検討する必要があります。 getaddrinfo
では、結果のメモリを自分で割り当てる必要があるため、この質問はしません。
いいえ、ポインタを直接使用できます。
(それについて考えてみましょう:メモリにアクセスできない、またはアクセスするのが安全でない場合はコピーできません。逆も同様です。コピーできる場合は、その場所でも使用できます)。
しかし、OSはどのようにこのメモリを消去するのかを知っていますか?私はそのメモリから読んでいる間、OSがそれをリフレッシュすることを恐れる。 –
@can:プロセスが終了すると、OSはメモリに触れるだけである。 'gethostbyaddr'によって返されたポインタは、カーネル空間へのポインタではありません。 –
これは機能ごとに異なります。私のBSDでは、 'gethostbyaddr'はスレッドローカルストレージを使い、このスレッドの後続の呼び出しでメモリが上書きされるだけだと述べています。他の実装では、 'gethostbyaddr'はスレッドに安全でないポインタを静的データに返すことがあります。他の機能は異なる動作をすることがあります(たとえば、メモリを解放する必要があります)。それぞれのドキュメントの説明を読む必要があります。 – hamstergene
典型的な実装は、スレッドローカルストレージへのポインタを返します。追加の電話をかけると、詳細なコピーを作成する方がよいでしょう。スレッドを使用していて、TLSが使用されているかどうかわからない場合は、ロックを使用することをお勧めします。 –
'gethostbyaddr'はシステムコールではなく、ライブラリルーチンです。システムコールであっても、カーネル空間にポインタを戻すことはありません。 –