Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Jul 2005 08:50:20 GMT
From:      Giorgos Keramidas <keramida@freebsd.org>
To:        freebsd-doc@FreeBSD.org
Subject:   Re: docs/82508: misleading man page for basename/dirname
Message-ID:  <200507010850.j618oKrr066578@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

The following reply was made to PR docs/82508; it has been noted by GNATS.

From: Giorgos Keramidas <keramida@freebsd.org>
To: Vlad Skvortsov <vss@73rus.com>
Cc: Vlad Skvortsov <vss@high.net.ru>, bug-followup@freebsd.org
Subject: Re: docs/82508: misleading man page for basename/dirname
Date: Fri, 1 Jul 2005 11:37:17 +0300

 On 2005-06-30 23:24, Vlad Skvortsov <vss@73rus.com> wrote:
 >Giorgos Keramidas wrote:
 >>On 2005-06-22 02:51, Vlad Skvortsov <vss@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 :-/
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507010850.j618oKrr066578>