9

これが私が閲覧していたソースです:glibcs​​ource。私の特定の質問は、この特定の関数のセットから生じます:ソケットライブラリ

たとえば(ほとんどの関数はこのように設定されています)socket/bind.cのソースは次のとおりです。

  19 #include <errno.h>
  20 #include <sys/socket.h>
  21 
  22 /* Give the socket FD the local address ADDR (which is LEN bytes long).  */
  23 int
  24 __bind (fd, addr, len)
  25      int fd;
  26      __CONST_SOCKADDR_ARG addr;
  27      socklen_t len;
  28 {
  29   __set_errno (ENOSYS);
  30   return -1;
  31 }
  32 
  33 weak_alias (__bind, bind)
  34 
  35 stub_warning (bind)
  36 #include <stub-tag.h>

あまり時間をかけなかったことは認めますが、実際の関数のコードはどこにあり、何が起こっているのでしょうか。これはよく使われるパラダイムですか?

4

2 に答える 2

9

__bind関数はスタブです。外部的には本物(同じプロトタイプ)のように見えますが、必要な関数を実行しない関数です。

weak_aliasマクロは、リンカーに、のbind弱いエイリアスになるように指示します__bind。つまり、この定義はbind弱い記号です。と呼ばれるシンボルの他の定義がない場合bind、この定義は有効です。の別の(非弱い)定義があるbind場合、その非弱い定義は有効であり、弱い定義は無視されます。弱いエイリアスは、別のシンボルのエイリアスである弱いシンボルです(それ自体で定義を持つのではありません)。そのstub_warning弱いエイリアスが使用されている場合、マクロによりリンカは警告を発します。

の実際の実装はbind、Glibcがコンパイルされているオペレーティングシステムによって異なります。Hurdでは、で定義されていsysdeps/mach/hurd/bind.cます。Linuxではbind、システムコールです。GlibcソースにはCコードはなく、アセンブリコードのみです。inまたはのアーキテクチャに依存する定義を再利用するbindが提供されます。これらの定義はすべて、基になるシステムコールの薄いラッパーであり、引数と戻り値を適切なレジスタにコピーするように注意します。sysdeps/unix/sysv/linux/bind.Ssocketsysdeps/unix/sysv/linux/**/socket.Sports/sysdeps/unix/sysv/linux/*/socket.S

于 2013-02-14T19:36:40.033 に答える
8

あなたは一般的なbind()の実装を見ていますが、これは... bind()がimplementetではないことを示しています(エラーを返し、errnoをENOSYSに設定します-syscallは実装されていません)。

glibcのプラットフォームに依存するシステムコールの多くはこのように機能します。エラーを返すだけのデフォルトの実装があり、各プラットフォーム/アーキテクターは、システムコールが存在する場合はその実装を提供する必要があります。

linux x86の実装については、たとえば./sysdeps/unix/sysv/linux/i386/socket.Sを参照してください。

もちろん、socket()は単なるシステムコールであるため、実際の実装はカーネル内にあります。Glibcは、それを呼び出すためのCラッパーを提供するだけです。

于 2013-02-14T19:19:22.360 に答える