docs/82508: misleading man page for basename/dirname
Vlad Skvortsov
vss at 73rus.com
Sat Jul 2 05:50:12 UTC 2005
The following reply was made to PR docs/82508; it has been noted by GNATS.
From: Vlad Skvortsov <vss at 73rus.com>
To: Giorgos Keramidas <keramida at freebsd.org>
Cc: Vlad Skvortsov <vss at high.net.ru>, bug-followup at freebsd.org
Subject: Re: docs/82508: misleading man page for basename/dirname
Date: Fri, 01 Jul 2005 22:45:48 -0700
Hey, I understand everything about that - and I don't ask to rework the
implementation of the functions. What I want is just to make the
documentaion more accurate on that point. If the man page would state
that those functions allocate storage and are not thread-safe, I
wouldn't have to look into the source code for the explanation of their
behaviour. That's my point. :-)
Giorgos Keramidas wrote:
> On 2005-06-30 23:24, Vlad Skvortsov <vss at 73rus.com> wrote:
>
>>Giorgos Keramidas wrote:
>>
>>>On 2005-06-22 02:51, Vlad Skvortsov <vss at high.net.ru> wrote:
>>>
>>>>The man pages for both basename(3) and dirname(3) state that the
>>>>functions return pointers to the internal _static_ storage.
>>>>However, those functions actually perform malloc() call to
>>>>allocate storage on the first invocation. Thus, the memory pointer
>>>>returned is actually a pointer to internal but dynamically
>>>>allocated storage.
>>>>
>>>>I don't know whether this violates standard or not, but the
>>>>documentation is misleading.
>>>
>>>The term 'static' here is a warning that these functions are not
>>>thread-safe.
>>>
>>>It does NOT mean that the ``bname'' object that is internal to
>>>basename() is actually an array declared as:
>>>
>>> char bname[MAXPATHLEN];
>>>
>>>It merely means that multiple invocations of the function from
>>>concurrent threads may clobber each other's data, so some form of
>>>locking should be used around calls to basename() from threaded
>>>applications or the function should be avoided altogether.
>>
>>Yes, I do understand what it supposed to mean. But, anyway, 'static'
>>means 'static', not (not only) 'thread-safe'. ;-)
>
>
> The storage *IS* accessed through a static pointer:
>
> 42: char *
> 43: dirname(path)
> 44: const char *path;
> 45: {
> 46: static char *bname = NULL;
> 47: const char *endp;
> 48:
> 49: if (bname == NULL) {
> 50: bname = (char *)malloc(MAXPATHLEN);
> 51: if (bname == NULL)
> 52: return(NULL);
> 53: }
>
>
>>I've ran into this issue while running a testsuite checking for memory leaks.
>>I expected those values to be static, not thread-safe.
>
>
> Oh, I see I think. So, basically, you're saying that dirname() and
> basename() trigger false positives in the memory leak detection tools
> you used.
>
> I think the reason `bname' is not declared as:
>
> static char bname[MAXPATHLEN];
>
> is to avoid actually allocating this array in the BSS area of programs
> that link with libc (practically every dynamic/shared executable on
> FreeBSD).
>
> This is exactly what the rationale for the change was, according to the
> CVS log of src/lib/libc/gen/dirname.c (rev. 1.6).
>
> AFAICT, there isn't an easy/clean way to have this automagically
> deallocated on program exit, which would let us keep both the malloc()
> call *and* make your memory leak detection tools happy :-/
>
--
Vlad Skvortsov, vss at 73rus.com, vss at high.net.ru
More information about the freebsd-doc
mailing list