Re: unterschiedliche bind(2) Implementierung FreeBSD/Linux?

From: Bernd Walter <ticso(at)cicely12.cicely.de>
Date: Sat, 8 Nov 2003 13:36:01 +0100

On Sat, Nov 08, 2003 at 10:46:23AM +0100, Matthias Teege wrote:
>
> Moin,
>
> ich bin gerade über einen kleinen Unterschied in der Verwendung von
> bind(2) zwischen Linux und FreeBSD gestolpert und habe in der
> Dokumentation nichts gefunden das mir sagt, welche Variante
> "richtig" ist.
>
> Das betreffende Programm möchte den Socket "dev/cgi" mit bind
> behandeln und ruft
>
> bind (sockfd, sa, socksize)
>
> auf. Unter Linux funktioniert das aber ein strace unter BSD zeigt
> mir
>
> bind(0, {sa_family=AF_UNIX, path="dev/cg"}, 8)
>
> Hmm, es fehlt das letzte Zeichen. Ich ändere also den Code auf
>
> bind (sockfd, sa, socksize+1)
>
> und siehe da, es wirkt
>
> bind(0, {sa_family=AF_UNIX, path="dev/cgi"}, 9)
>
> Leider ist mir nicht klar, warum BSD einen Länge von 9 Byte anstatt
> 8 braucht.

Folgendes:
struct sockaddr_un {
        unsigned char sun_len; /* sockaddr len including null */
        sa_family_t sun_family; /* AF_UNIX */
        char sun_path[104]; /* path name (gag) */
};

sun_len ist 1 Byte groß
sa_famility_t ebenfalls
Dein Pfad "dev/cgi" (soll der wirklich relativ sein?) ist 8 Byte groß.

Der Klassiker ist das '\0' Byte am Ende der Pathangabe zu vergessen.
Die gehört nämlich »nicht« dazu, wohl nicht dein Fehler.
Linux scheint das in einigen Fällen zu ignorieren, während FreeBSD
die Null mit zum Pfadnamen interpretiert.
Vorsicht übrigens bei der Verwendung vom SUN_LEN Macro - das ist bei
einigen Linux Distributionen kaput.
Am besten berechnest du es mit der FreeBSD Implementation:
/* actual length of an initialized sockaddr_un */
#define SUN_LEN(su) \
        (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))

Außerdem muss die Länge nicht in jedem System gleich sein, weswegen
die obige Berechnung entsprechend umfangreich ist.
sun_path darf nämlich an einer nahezu beliebigen Byteposition anfangen.

Wenn wir das mal durchspielen, dann berechnen wir für FreeBSD einen
sun_len Wert von 9, da die abschließende '\0' hierbei nicht mitgezählt
wird.
Und auch bei einem Linux wird sun_len und sun_family wenigstens ein
Byte groß sein, weswegen auch dort der richtige Wert eigendlich >=9
sein muß.

> Muss das so oder ist da irgendwo ein Fehler? Das BSD ist ein 4.8.

Ich vermute, daß du den Fehler auch unter Linux machst, aber Linux
ignoriert in dem Umfeld etliche Fehler.
Wie sieht denn deine Berechnung aus?

-- 
B.Walter                   BWCT                http://www.bwct.de
ticso(at)bwct.de                                  info(at)bwct.de
To Unsubscribe: send mail to majordomo.FreeBSD.org
with "unsubscribe de-bsd-questions" in the body of the message
Received on Sat 08 Nov 2003 - 13:36:40 CET

search this site