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?
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.
Bauform B. schrieb: > Bitte, wie macht man das richtig, danke? Das steht ebenfalls in der manpage, in der Sektion: EXAMPLES
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.
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 |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.