IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Opened 18 years ago

Closed 18 years ago

Last modified 18 years ago

#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 Paul Price, 18 years ago

Status: newassigned

GNU defines it in string.h

comment:2 by Michael Wood-Vasey, 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 Paul Price, 18 years ago

Resolution: fixed
Status: assignedclosed

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 Michael Wood-Vasey, 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 Paul Price, 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 Michael Wood-Vasey, 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 Michael Wood-Vasey, 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 Paul Price, 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".

Note: See TracTickets for help on using tickets.