Re: dirname return value



On Mon, 03 Jul 2006 15:54:38 -0700 (PDT), Ian Zimmerman <nobrowser@xxxxxxxxx> wrote:
thus http://www.opengroup.org/onlinepubs/009695399/functions/dirname.html:
The dirname() function may modify the string pointed to by path, and
may return a pointer to static storage that may then be overwritten by
subsequent calls to dirname().

Great, it's a MAY. How in the world do I know how to dispose with the
result pointer? It can be the same as the argument (nothing seems to
preclude that), a newly malloced one, or a static one.

Since dirname(3) may modify the storage passed to it through its
argument, it's not safe to assume that it can work correctly with data
that may be read-only (i.e. a `const char *' pointer). This means that
the following may not work correctly:

const char *foo = "/tmp/foo";
char *dname;

dname = dirname(foo);

Since dirname() is allowed to allocate storage internally and return a
pointer to that area, you will probably have to save the original
pointer and then compare it with the return value of dirname():

char foo[] = "/tmp/foo";
char *dname;

dname = dirname(foo);
if (dname == foo) {
...
} else {
....
}

But even this does not necessarily mean that you can free() the return
value of dirname() when it is not the same as the original, as it may be
just a static internal buffer of dirname() which is not obtained through
malloc().

These portability issues of dirname() usually force me to write my own
version, which has a more clean API:

char *xdirname(char *);

for which I know that the argument string is *NOT* modified at all, the
return value is a copy of the directory path of the argument, the return
value is obtained through malloc() and it is a responsibility of the
caller to free() the return value. This may or may not waste a bit more
memory than the original dirname(), but it is usually (for the programs
I write myself) far more easy to use without causing silly bugs :(

.