rewrite path normalize function

This commit is contained in:
sunphsjtu 2021-04-29 17:10:26 +08:00
parent 5d13421ae8
commit af847cc62e
2 changed files with 72 additions and 80 deletions

View File

@ -59,94 +59,86 @@ static struct MountPoint *GetMountPoint(const char *path)
return mp; return mp;
} }
char *GetAbsolutePath(const char *parent, const char *filename) char *GetAbsolutePath(const char *path)
{ {
char *abspath; char *abspath, *tmp;
char *dst0, *dst, *src; char *prev, *curr;
int len;
NULL_PARAM_CHECK(filename != NULL); NULL_PARAM_CHECK(path);
if (parent == NULL) if (path[0] == '/') {
parent = working_dir; len = strlen(path) + 1;
tmp = (char *)malloc(len);
if (filename[0] != '/') { if (tmp == NULL)
abspath = (char *)malloc(strlen(parent) + strlen(filename) + 2);
if (abspath == NULL)
return NULL; return NULL;
snprintf(abspath, strlen(parent) + strlen(filename) + 2, strcpy(tmp, path);
"%s/%s", parent, filename);
} else { } else {
abspath = strdup(filename); len = strlen(working_dir) + strlen(path) + 2;
if (abspath == NULL) tmp = (char *)malloc(len);
if (tmp == NULL)
return NULL; return NULL;
strcpy(tmp, working_dir);
strcat(tmp, "/");
strcat(tmp, path);
} }
src = abspath; abspath = (char *)malloc(len);
dst = abspath; if (abspath == NULL) {
free(tmp);
return NULL;
}
memset(abspath, 0, len);
dst0 = dst; for (curr = tmp; curr < tmp + len; curr++)
while (1) { if (*curr == '/')
char c = *src; *curr = '\0';
if (c == '.') { curr = tmp;
if (!src[1]) { while (curr < tmp + len) {
src++; if (*curr == '\0') {
} else if (src[1] == '/') { curr++;
src += 2; continue;
}
while ((*src == '/') && (*src != '\0')) if (*curr == '.') {
src ++; if (strlen(curr) == 1) {
continue; *curr = '\0';
} else if (src[1] == '.') { curr++;
if (!src[2]) { } else if (strlen(curr) == 2 && *(curr + 1) == '.') {
src += 2; prev = curr - 1;
goto up_one; while (prev >= tmp && *prev == '\0')
} else if (src[2] == '/') { prev--;
src += 3; if (prev >= tmp) {
while (prev > tmp && *(prev - 1) != '\0')
while ((*src == '/') && (*src != '\0')) prev--;
src ++; memset(prev, 0, strlen(prev));
goto up_one;
} }
*curr = *(curr + 1) = '\0';
curr += 2;
} }
} else {
curr += strlen(curr);
} }
while ((c = *src++) != '\0' && c != '/')
*dst++ = c;
if (c == '/') {
*dst ++ = '/';
while (c == '/')
c = *src++;
src --;
} else if (!c) {
break;
}
continue;
up_one:
dst--;
if (dst < dst0) {
free(abspath);
return NULL;
}
while (dst0 < dst && dst[-1] != '/')
dst --;
} }
*dst = '\0'; curr = tmp;
while (curr < tmp + len) {
if (*curr == '\0') {
curr++;
} else {
strcat(abspath, "/");
strcat(abspath, curr);
curr += strlen(curr);
}
}
dst --; if (abspath[0] == '\0') {
if ((dst != abspath) && (*dst == '/'))
*dst = '\0';
if ('\0' == abspath[0]) {
abspath[0] = '/'; abspath[0] = '/';
abspath[1] = '\0'; abspath[1] = '\0';
} }
free(tmp);
return abspath; return abspath;
} }
@ -453,7 +445,7 @@ int open(const char *path, int flags, ...)
return -1; return -1;
} }
abspath = GetAbsolutePath(NULL, path); abspath = GetAbsolutePath(path);
mp = GetMountPoint(abspath); mp = GetMountPoint(abspath);
if (mp == NULL) { if (mp == NULL) {
SYS_ERR("%s: mount point not found\n", __func__); SYS_ERR("%s: mount point not found\n", __func__);
@ -647,8 +639,8 @@ int rename(const char *from, const char *to)
return -1; return -1;
} }
abs_from = GetAbsolutePath(NULL, from); abs_from = GetAbsolutePath(from);
abs_to = GetAbsolutePath(NULL, to); abs_to = GetAbsolutePath(to);
mp_from = GetMountPoint(abs_from); mp_from = GetMountPoint(abs_from);
mp_to = GetMountPoint(abs_to); mp_to = GetMountPoint(abs_to);
if (mp_from == NULL || mp_from != mp_to) { if (mp_from == NULL || mp_from != mp_to) {
@ -692,7 +684,7 @@ int unlink(const char *path)
return -1; return -1;
} }
abspath = GetAbsolutePath(NULL, path); abspath = GetAbsolutePath(path);
mp = GetMountPoint(abspath); mp = GetMountPoint(abspath);
if (mp == NULL) { if (mp == NULL) {
SYS_ERR("%s: no mount point found\n", __func__); SYS_ERR("%s: no mount point found\n", __func__);
@ -734,7 +726,7 @@ int stat(const char *path, struct stat *buf)
return -1; return -1;
} }
abspath = GetAbsolutePath(NULL, path); abspath = GetAbsolutePath(path);
if (strcmp(abspath, "/") == 0) { if (strcmp(abspath, "/") == 0) {
buf->st_dev = 0; buf->st_dev = 0;
@ -879,7 +871,7 @@ int mkdir(const char *path, mode_t mode)
return -1; return -1;
} }
abspath = GetAbsolutePath(NULL, path); abspath = GetAbsolutePath(path);
mp = GetMountPoint(abspath); mp = GetMountPoint(abspath);
if (mp == NULL) { if (mp == NULL) {
SYS_ERR("%s: no mount point found\n", __func__); SYS_ERR("%s: no mount point found\n", __func__);
@ -929,7 +921,7 @@ DIR *opendir(const char *path)
} }
memset(fdp, 0, sizeof(struct FileDescriptor)); memset(fdp, 0, sizeof(struct FileDescriptor));
abspath = GetAbsolutePath(NULL, path); abspath = GetAbsolutePath(path);
mp = GetMountPoint(abspath); mp = GetMountPoint(abspath);
if (mp == NULL) { if (mp == NULL) {
SYS_ERR("%s: no mount point found\n", __func__); SYS_ERR("%s: no mount point found\n", __func__);
@ -1054,7 +1046,7 @@ int chdir(const char *path)
} }
closedir(dirp); closedir(dirp);
abspath = GetAbsolutePath(NULL, path); abspath = GetAbsolutePath(path);
KMutexObtain(working_dir_lock, WAITING_FOREVER); KMutexObtain(working_dir_lock, WAITING_FOREVER);
strcpy(working_dir, abspath); strcpy(working_dir, abspath);
@ -1126,7 +1118,7 @@ int statfs(const char *path, struct statfs *buf)
return -1; return -1;
} }
abspath = GetAbsolutePath(NULL, path); abspath = GetAbsolutePath(path);
mp = GetMountPoint(abspath); mp = GetMountPoint(abspath);
if (mp == NULL) { if (mp == NULL) {
SYS_ERR("%s: no mount point found\n", __func__); SYS_ERR("%s: no mount point found\n", __func__);

View File

@ -168,10 +168,10 @@ static int copy(const char *from, const char *to)
int abs_from_len, abs_to_len; int abs_from_len, abs_to_len;
char *last_name; char *last_name;
int last_name_len; int last_name_len;
char *GetAbsolutePath(const char *parent, const char *filename); char *GetAbsolutePath(const char *path);
abs_from = GetAbsolutePath(NULL, from); abs_from = GetAbsolutePath(from);
abs_to = GetAbsolutePath(NULL, to); abs_to = GetAbsolutePath(to);
if (abs_from == NULL || abs_to == NULL) if (abs_from == NULL || abs_to == NULL)
goto err; goto err;