tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: dirname(3) used on its own results?



    Date:        Tue, 25 Sep 2018 16:32:03 +1000
    From:        Simon Burge <simonb%NetBSD.org@localhost>
    Message-ID:  <20180925063203.2B929204D3%thoreau.thistledown.com.au@localhost>

  | Is the correct fix to use memmove(3) instead of memcpy(3) inside
  | dirname(3), or are we restricted by some standard from having dirname(3)
  | be able to be called on the results of a previous dirname(3) call in
  | which case we should document this in the manpage?

We are going to need change anyway, as POSIX is changing to require
thread safe implementations of dirname() (and basename()).

Currently it says ...

	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 a subsequent
	call to dirname( ).

Returning a pointer to static storage, which can be destroyed by a subsequent
call more or less demands that if the result is to be retained / modified it 
should be copied first.   That dirname() is allowed to modify its input arg 
means that calling dirname is modifying the input, which means that if that
came from a previous dirname call, it needs to be copied.

What it is going to say (approved update for next revision) is ...

	The dirname() function may modify the string pointed to by path, and may
	return a pointer into the input string. The returned pointer might be invalidated
	if the input string is subsequently modified or freed. If path does not contain a '/', 
	is a null pointer, or points to an empty string the returned pointer may point to
	constant data that cannot be modified.

That is, it is now expected, not just allowed, to modify its input and return 
a pointed to some part of the original input.   That allowws thread safety.   
But sometimes that cannot be done (the input is not lonng enough to contain
the required result) when that happens, a const char * result (which obviously
cannot be modified) can be returned (this allows return "." and return "/" in
appropriate cases).   Since the result might be a string that cannot be 
modifried, and the input is expected to be modified, calling dirname() with the
result of a previous dirname() is never safe.

In general, unless the result from dirname() is to be used and forgotten 
immediately (eg: used in a printf, or an sprintf to generate a different 
filename) it should always be strdup'd - what's more, the input should
usually be a copy of the actual string.

All of this appolies to namename() as well as dirname()

kre




Home | Main Index | Thread Index | Old Index