diff options
| author | Charles Forsyth <charles.forsyth@gmail.com> | 2013-06-06 21:01:19 +0000 |
|---|---|---|
| committer | Charles Forsyth <charles.forsyth@gmail.com> | 2013-06-06 21:01:19 +0000 |
| commit | 7ded4a527bdfd0e8b3a9049955f2af89e5f039ee (patch) | |
| tree | 7ee0f03dd4e5cad072bc0c816468ebfd0dd17c67 /lib9/cleanname.c | |
| parent | 8bdf904b6a23b93336ae2837772110bcdad234ce (diff) | |
sync with Plan 9
Diffstat (limited to 'lib9/cleanname.c')
| -rw-r--r-- | lib9/cleanname.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/lib9/cleanname.c b/lib9/cleanname.c index baf11557..c9e539a5 100644 --- a/lib9/cleanname.c +++ b/lib9/cleanname.c @@ -1,4 +1,4 @@ -#include <lib9.h> +#include "lib9.h" /* * In place, rewrite name to compress multiple /, eliminate ., and process .. @@ -8,9 +8,10 @@ char* cleanname(char *name) { char *p, *q, *dotdot; - int rooted; + int rooted, erasedprefix; rooted = name[0] == '/'; + erasedprefix = 0; /* * invariants: @@ -23,9 +24,11 @@ cleanname(char *name) while(*p) { if(p[0] == '/') /* null element */ p++; - else if(p[0] == '.' && SEP(p[1])) + else if(p[0] == '.' && SEP(p[1])) { + if(p == name) + erasedprefix = 1; p += 1; /* don't count the separator in case it is nul */ - else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) { + } else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) { p += 2; if(q > dotdot) { /* can backtrack */ while(--q > dotdot && *q != '/') @@ -37,6 +40,8 @@ cleanname(char *name) *q++ = '.'; dotdot = q; } + if(q == name) + erasedprefix = 1; /* erased entire path via dotdot */ } else { /* real path element */ if(q != name+rooted) *q++ = '/'; @@ -47,5 +52,11 @@ cleanname(char *name) if(q == name) /* empty string is really ``.'' */ *q++ = '.'; *q = '\0'; + if(erasedprefix && name[0] == '#'){ + /* this was not a #x device path originally - make it not one now */ + memmove(name+2, name, strlen(name)+1); + name[0] = '.'; + name[1] = '/'; + } return name; } |
