linux manual impl of get_canonical to handle non-existent paths

master
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
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);
if(path){
size_t path_len = strlen(path);
if(max >= path_len){
memcpy(buffer, path, path_len);
result = path_len;
while(read_p < filename + len){
if(read_p == filename || read_p[0] == '/'){
if(read_p[1] == '/'){
++read_p;
} else if(read_p[1] == '.'){
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(strncmp(filename, path, len) != 0){
LINUX_FN_DEBUG("[%.*s] -> [%s]", len, filename, path);
if(len != (write_p - path) || memcmp(filename, path, len) != 0){
LINUX_FN_DEBUG("[%.*s] -> [%.*s]", len, filename, (int)(write_p - path), path);
}
#endif
free(path);
} else {
LINUX_FN_DEBUG("[%.*s] -> [null]", len, filename);
}
return result;
return write_p - path;
}
internal