यहाँ एक normalize_path है () फ़ंक्शन:
यदि दिया गया पथ सापेक्ष है, तो फ़ंक्शन वर्तमान कार्य निर्देशिका को पूर्ववत करके शुरू होता है।
फिर विशेष..
जैसे पथ घटक, .
या खाली घटकों का इलाज किया जाता है, और परिणाम वापस आ जाता है।
..
के लिए, अंतिम घटक हटा दिया जाता है यदि कोई है (/..
बस /
वापस करेगा)।
.
या खाली घटकों (डबल /
) के लिए, यह अभी छोड़ दिया गया है।
फ़ंक्शन खाली पथ वापस नहीं लौटाता है (/
इसके बदले में लौटाया जाता है)।
#define _GNU_SOURCE /* memrchr() */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
char * normalize_path(const char * src, size_t src_len) {
char * res;
size_t res_len;
const char * ptr = src;
const char * end = &src[src_len];
const char * next;
if (src_len == 0 || src[0] != '/') {
// relative path
char pwd[PATH_MAX];
size_t pwd_len;
if (getcwd(pwd, sizeof(pwd)) == NULL) {
return NULL;
}
pwd_len = strlen(pwd);
res = malloc(pwd_len + 1 + src_len + 1);
memcpy(res, pwd, pwd_len);
res_len = pwd_len;
} else {
res = malloc((src_len > 0 ? src_len : 1) + 1);
res_len = 0;
}
for (ptr = src; ptr < end; ptr=next+1) {
size_t len;
next = memchr(ptr, '/', end-ptr);
if (next == NULL) {
next = end;
}
len = next-ptr;
switch(len) {
case 2:
if (ptr[0] == '.' && ptr[1] == '.') {
const char * slash = memrchr(res, '/', res_len);
if (slash != NULL) {
res_len = slash - res;
}
continue;
}
break;
case 1:
if (ptr[0] == '.') {
continue;
}
break;
case 0:
continue;
}
res[res_len++] = '/';
memcpy(&res[res_len], ptr, len);
res_len += len;
}
if (res_len == 0) {
res[res_len++] = '/';
}
res[res_len] = '\0';
return res;
}
"/dir/a_random_synlink/../hello" का नतीजा क्या होना चाहिए? याद रखें कि यह "/ dir/hello" जैसा ही नहीं हो सकता है अगर a_random_synlink एक ही निर्देशिका में निर्देशिका को इंगित नहीं करता – BatchyX
@ बैचएक्स: मानक व्यवहार मानता है: 'readlink -v -m'/home/user/linktoslashtmp /../ 'रिटर्न '/ home/user' – thejh
शायद रीडलिंक यह करता है, लेकिन अंतर्निहित ओएस नहीं करता है। एलएस/होम/उपयोगकर्ता/linktoslashtmp/..// – BatchyX