From: Wang Yufen <[email protected]>

I tested basename(path), path is "///", the basename(path) returned "/",
but the input path also be modified to "/". It because in basename impl, 
"last[1] = 0;" modified the input path, I think that isn't correct. 

This patch fix this problem. 

Signed-off-by: Wang Yufen <[email protected]>
---
 libc/string/__xpg_basename.c |   54 +++++++++++++++++++++++++++--------------
 1 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/libc/string/__xpg_basename.c b/libc/string/__xpg_basename.c
index 2e7ade9..4d5a984 100644
--- a/libc/string/__xpg_basename.c
+++ b/libc/string/__xpg_basename.c
@@ -6,33 +6,49 @@
  */
 
 #include <libgen.h>
-
-char *__xpg_basename(register char *path)
+#include <string.h>
+char *__xpg_basename (char *path)
 {
-       static const char null_or_empty[] = ".";
-       char *first;
-       register char *last;
-
-       first = (char *) null_or_empty;
+       char *p;
 
-       if (path && *path) {
-               first = path;
-               last = path - 1;
+       if (path == NULL || path[0] == '\0')
+               /* We return a pointer to a static string containing ".".  */
+               p = (char *) ".";
+       else {
+               p = strrchr (path, '/');
 
-               do {
-                       if ((*path != '/') && (path > ++last)) {
-                               last = first = path;
-                       }
-               } while (*++path);
+               if (p == NULL)
+                       /* There is no slash in the filename.  Return the whole 
string.  */
+                       p = path;
+               else {
+                       if (p[1] == '\0') {
+                               /* We must remove trailing '/'.  */
+                               while (p > path && p[-1] == '/')
+                                       --p;
 
-               if (*first == '/') {
-                       last = first;
+                               /* Now we can be in two situations:
+                                  a) the string only contains '/' characters, 
so we return
+                                  '/'
+                                  b) p points past the last component, but we 
have to remove
+                                  the trailing slash.  */
+                               if (p > path) {
+                                       *p-- = '\0';
+                                       while (p > path && p[-1] != '/')
+                                               --p;
+                               } else
+                                       /* The last slash we already found is 
the right position
+                                          to return.  */
+                                       while (p[1] != '\0')
+                                               ++p;
+                       } else
+                               /* Go to the first character of the name.  */
+                               ++p;
                }
-               last[1] = 0;
        }
 
-       return first;
+       return p;
 }
+
 #ifndef __USE_GNU
 # undef basename
 weak_alias(__xpg_basename,basename)
-- 
1.7.1


_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to