Date: Tue, 25 Sep 2018 16:32:03 +1000 From: Simon Burge <sim...@netbsd.org> Message-ID: <20180925063203.2b92920...@thoreau.thistledown.com.au>
| 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