Hallo,
ich bin letztens über einen versteckten Bug gestolpert, und weil er so fies war, schreib ich gleich mal ein paar Worte dazu...
Die Funktion getpwnam(), Bestandteil der libc, konform zu 4.3BSD und POSIX, liefert eine Struktur, die im großen und ganzen einer Zeile in der /etc/passwd entspricht. Sehr praktisch, wenn man z.B. die User-ID und die Shell eines Nutzers herausfinden möchte. Es gibt 2 Situationen, in denen NULL zurückgegeben wird: - der Nutzer existiert nicht - es tritt ein Fehler auf
Da bei mir nach einer gewissen Zeit immer NULL geliefert wurde und der Nutzer ziemlich existent ist, blieb mir also nichts anderes übrig als die Variable errno auszuwerten, die aber dummerweise für getpwnam() nur den Wert ENOMEM annehmen kann, und Speicher war genügend vorhanden.
Der Bug befindet sich in der Manpage; diese verschweigt, daß auch EMFILE auftreten kann, weil nämlich für getpwnam() die Datei /etc/passwd geöffnet werden muß, und damit auch bei Mangel an Dateideskriptoren der Aufruf fehlschlagen muß. (Die glibc-2.2.5-Quellen dazu sind nicht wirklich lesbar...)
Wo liegt der Bug nun genau? Manpage oder POSIX oder glibc-Implementation? Das EMFILE sollte auf alle Fälle mit dokumentiert sein, da das Öffnen von /etc/passwd transparent erfolgt. Nach einem Update von manpages-dev liest sich getpwnam(3) etwas anders, dabei wird die /etc/nsswitch.conf mit erwähnt, das sollte aber nichts an der Sache ändern.
Josef Spillner
Am Dienstag, dem 02. April 2002 um 23:09:06, schrieb Josef Spillner:
Da bei mir nach einer gewissen Zeit immer NULL geliefert wurde und der Nutzer ziemlich existent ist, blieb mir also nichts anderes übrig als die Variable errno auszuwerten, die aber dummerweise für getpwnam() nur den Wert ENOMEM annehmen kann, und Speicher war genügend vorhanden.
Ich denke getpwnam() erzeugt tatsächlich nur ENOMEM als möglichen Fehler, reicht aber Fehler des darunterliegenden PAM-Mechanismus mit durch. Wahrscheinlich kann dadurch auch ein EACCES, EAGAIN und ähnliches zurück kommen. Der Autor der man page kann nicht alle Varianten deines lokalen Systems kennen.
Torsten
On Tue, 02 Apr 2002 23:09:06 +0200, Josef Spillner wrote:
Die Funktion getpwnam(), Bestandteil der libc, konform zu 4.3BSD und POSIX,
...
Der Bug befindet sich in der Manpage; diese verschweigt, daß auch EMFILE auftreten kann, weil nämlich für getpwnam() die Datei /etc/passwd geöffnet werden muß, und damit auch bei Mangel an Dateideskriptoren der Aufruf fehlschlagen muß. (Die glibc-2.2.5-Quellen dazu sind nicht wirklich lesbar...)
Wo liegt der Bug nun genau? Manpage oder POSIX oder glibc-Implementation?
Im Manual. Wenn irgendwo Posix steht weiss man nie, was genau gemeint ist. Da gibts viele Versionen und kaum einer hat die Doku dazu. Letztes Jahr ist glücklicherweise (ich hoffe ich habe das richtig verstanden) ein gemeinsamer Nachfolger von SUS V2 und Posix 1003.1* rausgekommen. Das nennt sich SUS V3 oder auch IEEE 1003.1-2001 und die Doku ist praktisch frei verfügbar (eigentlich muß man sich registrieren) Ich denke mal, daß die glibc auf Komaptibilität zu diesem Standard getrimmt wird/wurde. Da steht dann u.a. auch auch EMFILE für getpwnam drin.
http://www.opengroup.org/onlinepubs/007904975/functions/getpwnam.html
Lies mal "issue 6" dort. Daraus kann man ableiten, daß EMFILE usw. in POSIX-kompatiblen libs aus der BSD-Ecke (oder nicht SUS-Ecke) sicherlich fehlen wird. Von daher auch das alte manual.
Da die manpages oft veraltet sind lohnt sich IMO immer ein Blick in die genannte Doku.
SUS V2: http://www.opengroup.org/onlinepubs/007908799/ SUS V3: http://www.opengroup.org/onlinepubs/007904975/
Ich finde die Seiten auch als Info zu /bin/sh, awk, ... ohne GNU-Erweiterungen sehr praktisch.
Reinhard
lug-dd@mailman.schlittermann.de