#1142 closed defect (fixed)
"basename" not defined
| Reported by: | Michael Wood-Vasey | Owned by: | Paul Price |
|---|---|---|---|
| Priority: | high | Milestone: | |
| Component: | ppStack | Version: | 2.6 |
| Severity: | minor | Keywords: | |
| Cc: |
Description
Hi Paul,
In the latest CVS HEAD, r. 1.74 of 'src/ppStackLoop.c' inserted new code:
189a190,201
const char *tempDir = psMetadataLookupStr(NULL, recipe, "TEMP.DIR"); Directory for temporary images
if (!tempDir) {
psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find TEMP.DIR in recipe");
return false;
}
const char *tempName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); Name for temporary files
tempName = basename(tempName);
if (!tempName) {
psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to construct basename for temporary files.");
return false;
}
but there's no definition of the 'basename' function. Where is this supposed to be defined?
Change History (8)
comment:1 by , 18 years ago
| Status: | new → assigned |
|---|
comment:2 by , 18 years ago
You'll of course be pleased to learn that this is not in BSD "string.h". It is instead defined in "libgen.h", which essentially sole exists for this purpose, as far as I can tell. It's just a bit different that the GNU version in that it may strip trailing '/'. For more details you can refer to
http://www.gnu.org/software/libtool/manual/libc/Finding-Tokens-in-a-String.html
In the meantime, just including "libgen.h" fixes this. But this may have to be conditional. I don't know if all GNU-based system will have "libgen.h".
comment:3 by , 18 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
I feared this might be an issue.
Let's just include libgen.h. It should be safe (we won't have trailing slashes). You wanna check your fix in?
comment:4 by , 18 years ago
Oh, and you're not going to like this, but the definition in "libgen.h" is for
the argument of "basename" to be a "const char *", so you're not supposed to
modify it, so
tempName = basename(tempName);
doesn't work because the compiler will object if tempName is modifiable because
it will violate the "basename" prototype and it will object if it is not
modifiable because the above assignment will obviously fail. In fact, I'm
mildly suprised that
const char *tempName = psMetadataLookupStr(NULL, config->arguments,
"OUTPUT"); Name for temporary files
tempName = basename(tempName);
works under any definition of "basename". "const char *" should never be
changed and this should be enforced by the compiler. I changed it to doing
everything on one line:
const char *tempName = basename(psMetadataLookupStr(NULL,
config->arguments, "OUTPUT")); Name for temporary files
and then it compiled fine (with an added "#include <libgen.h>" after the
"#include <string.h>").
Here's the final diff. I'll check it in shortly.
diff -r1.74 ppStackLoop.c
7a8
#include <libgen.h>
195,196c196
< const char *tempName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); Name for temporary files
< tempName = basename(tempName);
---
const char *tempName = basename(psMetadataLookupStr(NULL, config->arguments, "OUTPUT")); Name for temporary files
comment:5 by , 18 years ago
If it's possible that basename() is going to modify the contents, you should copy the string before passing it in. Use psStringCopy(), and don't forget to free it when done.
comment:6 by , 18 years ago
OK. Will do. Some "basename" prototypes promise not to modify it, others don't, so we'll have to assume that it can be.
comment:7 by , 18 years ago
As in something like this?
"""
psString outputName = psStringCopy(psMetadataLookupStr(NULL, config->arguments, "OUTPUT")); Name for temporary files
const char *tempName = basename(outputName);
psFree(outputName);
"""
comment:8 by , 18 years ago
You may be blowing away "tempName" when you free "outputName". You need to hang on to "outputName" until you're done with "tempName".

GNU defines it in string.h