Reputation: 2045
In my program , I use basename function to get the partition. first , I write a if sentence like this:
if (!strncmp(buf,
basename("/dev/mmcblk0p3"),
strlen(basename("/dev/mmcblk0p3"))) {
ret = 1;
} else {
ret = 0;
}
buf point to string "mmcblk0p3" , but the ret = 0, using gdb, I found basename("/dev/mmcblk0p3") returned a weird string, but when i changed the program like this:
char *p = NULL;
p = basename("/dev/mmcblk0p3");
if (!strncmp(buf, p, strlen(p)) {
ret = 1;
} else {
ret = 0;
}
the ret is 1, the program runs normal. What is the difference? basename cannot be used like this ? Compiling environment is armel7v/gcc.
Upvotes: 2
Views: 103
Reputation: 726479
One consequence of using a non-reentrant function basename that returns a string is that your subsequent invocations invalidate the prior results. You need to make a copy of the return value before making a second call, or stop using the old value after the second call has returned. This is because basename has only one internal buffer to store its result, assuming that it does not modify its parameter ( which looks to be the case with your program, because it does not crash on a string literal; still, it's undefined behavior).
Modify your program as follows to make it portable:
char *p = NULL;
char pathname[] = "/dev/mmcblk0p3";
p = basename(pathname);
if (!strncmp(buf, p, strlen(p)) {
ret = 1;
} else {
ret = 0;
}
Upvotes: 1
Reputation: 399723
The classical (POSIX) basename()
function may modify its input string.
It seems your version is modifying the input, so the second call is not getting the same string as the first, making the above code very confusing.
Worse: you're also invoking undefined behavior by having basename()
modify a string literal.
Upvotes: 3