linux manual impl of get_canonical to handle non-existent paths

This commit is contained in:
insofaras 2016-09-01 20:30:09 +01:00
parent c82dbd8e2c
commit 0ad5165cf2
1 changed files with 34 additions and 15 deletions

View File

@ -499,26 +499,45 @@ Sys_Set_File_List_Sig(system_set_file_list){
internal internal
Sys_Get_Canonical_Sig(system_get_canonical){ Sys_Get_Canonical_Sig(system_get_canonical){
int32_t result = 0; char* path = (char*) alloca(len + 1);
char* write_p = path;
const char* read_p = filename;
char* path = realpath(strndupa(filename, len), NULL); while(read_p < filename + len){
if(path){ if(read_p == filename || read_p[0] == '/'){
size_t path_len = strlen(path); if(read_p[1] == '/'){
if(max >= path_len){ ++read_p;
memcpy(buffer, path, path_len); } else if(read_p[1] == '.'){
result = path_len; if(read_p[2] == '/' || !read_p[2]){
read_p += 2;
} else if(read_p[2] == '.' && (read_p[3] == '/' || !read_p[3])){
while(write_p > path && *--write_p != '/');
read_p += 3;
} else {
*write_p++ = *read_p++;
} }
} else {
*write_p++ = *read_p++;
}
} else {
*write_p++ = *read_p++;
}
}
if(write_p == path) *write_p++ = '/';
if(max >= (write_p - path)){
memcpy(buffer, path, write_p - path);
} else {
write_p = path;
}
#if FRED_INTERNAL #if FRED_INTERNAL
if(strncmp(filename, path, len) != 0){ if(len != (write_p - path) || memcmp(filename, path, len) != 0){
LINUX_FN_DEBUG("[%.*s] -> [%s]", len, filename, path); LINUX_FN_DEBUG("[%.*s] -> [%.*s]", len, filename, (int)(write_p - path), path);
} }
#endif #endif
free(path);
} else {
LINUX_FN_DEBUG("[%.*s] -> [null]", len, filename);
}
return result; return write_p - path;
} }
internal internal