Forum: Compiler & IDEs Debian, glibc, basename(3) -- das ist doch ein Scherz?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bauform B. (bauformb)


Lesenswert?

Mahlzeit!

char *basename(char *path);

die man page fängt schon gut an, da fehlt ein "const" und noch besser: 
"Warning: there are two different functions basename()". Und 
tatsächlich: "basename() may modify the contents of path". Unter 
Umständen bekomme ich die andere Version
char *basename (const char *__filename);
"The  GNU  version  never  modifies  its argument"

Das ist mir zu unsicher. Oder kann ich beim Übersetzen oder zur Laufzeit 
prüfen, welche dazu gelinkt wurde?

Mit einer eigenen basename() wird keine aus der libc benutzt, aber das 
scheint mir auch nicht wasserdicht zu sein. Außerdem darf ich die nicht 
in meiner lib.h definieren, das wäre redundant.

Mit my_basename() oder base_name() wäre zwar alles einwandfrei sauber, 
aber das nützt mir nichts. Wer den Pfad aufspalten will, schreibt nicht 
my_ davor. OK, immerhin müsste ich dann nur prüfen, ob irgendeine 
basename() dazu gelinkt wurde, aber wie?

Bitte, wie macht man das richtig, danke?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Was man machen kann ist vorher eine Kopie von Filename anzulegen.

Und wenn zwischen dem Aufruf von basename() und der Verwendung des 
Ergebnisses weitere Aufrufe von basename() getätigt werden, dann auch 
das Ergebnis kopieren, etwa mit stp[n]cpy oder str[n]cpy.

Bzw. einen entsprechenden Wrapper um basename() bauen.

Falls basename() nicht millionenfach verwendet wird, wirst du das an der 
Performance nicht merken.  Und wenn du es doch merkst, dann bist du 
vielleicht sogar froh wenn basename() nicht einen neuen malloc String 
liefert sondern einen Pointer in den übergebenen Dateiname.

von Norbert (der_norbert)


Lesenswert?

Bauform B. schrieb:
> Bitte, wie macht man das richtig, danke?

Das steht ebenfalls in der manpage, in der Sektion: EXAMPLES

von Ein T. (ein_typ)


Lesenswert?

Bauform B. schrieb:
> Bitte, wie macht man das richtig, danke?

Das kommt darauf an, wie portabel Du es haben möchtest. Wann welche 
Variante der basename(3) benutzt wird, steht allerdings in der Manpage. 
Da steht auch, wie man darauf hinarbeiten kann, welche Version verwendet 
wird, und wie man die Modifikation bei der POSIX-Version unterbinden 
kann, sogar mit Beispiel.

von Bauform B. (bauformb)


Lesenswert?

Danke, ich hab' das F* M* gelesen ;) Erstmal werde dafür sorgen, dass 
basename() garnicht gebraucht wird. Zweitens gibt make ggf. eine Warnung 
aus:
1
@nm $@ | grep -Z -o --color basename && \
2
printf 'WAHRSCHAU: basename() may modify the contents of path\n'; true

von Markus F. (mfro)


Lesenswert?

Mac OS definiert ein
1
basename_r(const char *path, char *bname)
 wobei der Aufrufer in bname mindestens MAXPATHLEN Bytes bereitstellen 
muss.

Das lässt sich mit der GNU version leicht auch für Linux nachrüsten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.