Je parcourais la glibc quand je suis tombé sur le code du socket, quelqu’un peut-il expliquer ce qui se passe?

Voici la source que je parcourais: la source glibc . Ma question particulière découle de cet ensemble de fonctions: la bibliothèque de socket .

Par exemple (la plupart des fonctions sont configurées de cette façon) le source de socket/bind.c est:

  19 #include  20 #include  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  

J’admets que je n’ai pas passé beaucoup de temps, mais où est exactement le code pour la fonction réelle et que se passe-t-il? Est-ce un paradigme bien utilisé?

La fonction __bind est un stub : c’est une fonction qui ressemble extérieurement à la réalité (même prototype) mais qui n’exécute pas la fonction requirejse.

La macro weak_alias indique à l’éditeur de liens que la bind est un alias faible pour __bind . C’est-à-dire que cette définition de bind est un symbole faible . S’il n’y a pas d’autre définition d’un symbole appelé bind , cette définition est conservée; s’il existe une autre définition (non faible) de bind cette définition non valide est conservée et la définition faible est ignorée. Un alias faible est un symbole faible qui est un alias d’un autre symbole (par opposition à une définition propre). La macro stub_warning amène l’éditeur de liens à émettre un avertissement si cet alias faible est utilisé.

La mise en œuvre réelle de bind dépend du système d’exploitation pour lequel Glibc est compilé. Sur Hurd , il est défini dans sysdeps/mach/hurd/bind.c Sous Linux, bind est un appel système: il n’existe pas de code C dans le code source de Glibc, mais uniquement du code assembleur. bind est fourni dans sysdeps/unix/sysv/linux/bind.S qui réutilise la définition de socket dépendant de l’architecture dans sysdeps/unix/sysv/linux/**/socket.S ou ports/sysdeps/unix/sysv/linux/*/socket.S . Ces définitions sont toutes des enveloppes minces autour de l’appel système sous-jacent, en prenant soin de copier l’argument et les valeurs de retour dans les registres appropriés.

Vous regardez l’implémentation générale de bind () qui … vous indique simplement que bind () n’est pas implémenté (Il renvoie simplement une erreur et définit errno sur ENOSYS – appel système non implémenté.).

De nombreux appels système dépendant de la plate-forme dans glibc fonctionnent de cette manière: il existe une implémentation par défaut qui renvoie simplement une erreur, et chaque plate-forme / architecte doit fournir une implémentation de l’appel système, le cas échéant.

Recherchez, par exemple, dans ./sysdeps/unix/sysv/linux/i386/socket.S, l’implémentation Linux x86.

Bien sûr, socket () n’est qu’un appel système, l’implémentation proprement dite est donc dans le kernel. Glibc fournit simplement un wrapper en C pour l’appeler.