2013-02-14 9 views
9

Hier ist die Quelle, die ich suchte: glibc source. Meine spezielle Frage ergibt sich aus diesem speziellen Satz von Funktionen: socket library.Ich habe Glibc gelesen, als ich auf den Socket-Code stieß, kann jemand erklären, was vor sich geht?

Zum Beispiel (die meisten Funktionen sind auf diese Weise eingerichtet) socket/bind.c ‚s Quelle:

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> 

ich zugeben, dass ich nicht viel Zeit verbracht haben, aber wo genau ist der Code für die eigentliche Funktion und was ist los? Ist das ein gut verwendetes Paradigma?

Antwort

9

Die __bind Funktion ist eine stub: es ist eine Funktion, die äußerlich wie die reale Sache aussieht (gleicher Prototyp), aber nicht die erforderliche Funktion erfüllt.

Das weak_alias Makro teilt dem Linker mit, dass bind ein schwaches Alias ​​für __bind sein soll. Das heißt, diese Definition von bind ist eine weak symbol. Wenn es keine andere Definition eines Symbols namens bind gibt, steht diese Definition; Wenn es eine andere (nicht schwache) Definition von bind gibt, dann steht diese nicht-schwache Definition und die schwache Definition wird ignoriert. Ein schwaches Alias ​​ist ein schwaches Symbol, das ein Alias ​​eines anderen Symbols ist (im Gegensatz zu einer eigenständigen Definition). Das Makro stub_warning verursacht, dass der Linker eine Warnung ausgibt, wenn dieser schwache Alias ​​verwendet wird.

Die tatsächliche Implementierung von bind hängt vom Betriebssystem ab, für das Glibc kompiliert wurde. Auf Hurd ist es in sysdeps/mach/hurd/bind.c definiert. Unter Linux ist bind ein Systemaufruf: Es gibt keinen C-Code in der Glibc-Quelle, nur Assemblercode. bind wird in sysdeps/unix/sysv/linux/bind.S bereitgestellt, die die architekturabhängige Definition von socket in sysdeps/unix/sysv/linux/**/socket.S oder ports/sysdeps/unix/sysv/linux/*/socket.S wiederverwendet. Diese Definitionen sind allesamt dünne Wrapper um den zugrundeliegenden Systemaufruf, wobei darauf geachtet wird, das Argument und die Rückgabewerte in die richtigen Register zu kopieren.

8

Sie betrachten die allgemeine bind() - Implementierung, die ... Ihnen nur sagt, dass bind() nicht implementiert ist (Es gibt nur einen Fehler zurück und setzt errno auf ENOSYS - syscall nicht implementiert.).

Viele plattformabhängige Systemaufrufe in glibc funktionieren auf diese Weise - es gibt eine Standardimplementierung, die nur einen Fehler zurückgibt, und jede Plattform/jeder Architektor muss eine Implementierung des Systemaufrufs bereitstellen, falls eine existiert.

Schauen Sie z.B. ./sysdeps/unix/sysv/linux/i386/socket.S für die Linux x86-Implementierung.

Natürlich ist socket() nur ein Systemaufruf, daher befindet sich die eigentliche Implementierung im Kernel. Glibc stellt nur einen C-Wrapper zum Aufruf bereit.

+0

Dies war genau das, was ich wissen musste. Ich hatte den Verdacht, dass dies eine Art Skelett war, aber ich hatte keine Ahnung, wo ich sonst nach der Implementierung suchen sollte. Ihre Antwort war knapp, schnell und hilfreich. Ich wollte sehen, was der Wrapper für socket() war und Ihre Tipps helfen mir, die Suche fortzusetzen! – GRAYgoose124