Вы уверены, что может быть решение? Я считаю, что нет (потому что некоторые каталоги могут быть опечатками или символическими ссылками, которые должны быть созданы).
Что вы ожидаете от своей функции betterrealpath
для возврата на /tmp/someinexistentdirectory/foobar
? Возможно, намерение пользователя было символической ссылкой от его $HOME
до /tmp/someinexistentdirectory
? Или, может быть, это опечатка, и пользователь хочет /tmp/someexistentdirectory/foobar
...? А как насчет /tmp/someinexistentdirectory/../foobar
? Должен ли он быть канонизирован как /tmp/foobar
? Зачем?
Возможно, используя первый dirname(3), а затем сделать realpath(3) на этом, а затем добавить basename(3) аргумента должно быть достаточно? В C-то вроде:
const char*origpath = something();
char*duppath = strdup(origpath);
if (!duppath) { perror("strdup"); exit(EXIT_FAILURE); };
char*basepath = basename(duppath);
char*dirpath = dirname(duppath);
char*realdirpath = realpath(dirpath, NULL);
if (!realdirpath) { perror("realpath"); exit(EXIT_FAILURE); };
char* canonpath = NULL;
if (asprintf(&canonpath, "%s/%s", realdirpath, basepath) <= 0)
{ perror("asprintf"); exit(EXIT_FAILURE); };
free (duppath), duppath = NULL;
basepath = NULL, dirpath = NULL;
/// use canonpath below, don't forget to free it
Конечно этот пример не будет работать для /tmp/someinexistentdirectory/foobar
, но будет работать на /home/violet/missingfile
, предполагая, что ваш домашний каталог /home/violet/
и доступен (читаемый & исполняемый файл) ...
Не стесняйтесь улучшать или адаптировать к C++ приведенный выше код. Не забывайте обрабатывать сбои.
Помните, что i-nodes являются центральными для файловых систем POSIX. Файл (включая каталог) может иметь один, нулевой или несколько путей к файлу ... Имя каталога (или файла) может быть rename
-d другим ходом процесса ...
Возможно, вы хотите использовать каркас, такой как Qt или POCO; они могли бы обеспечить что-то достаточно хорошее для вас ...
На самом деле, я предлагаю вам код вашей betterrealpath
функции полностью самостоятельно, используя толькоsyscalls(2) на Linux. Затем вы должны думать обо всех странных случаях ... Кроме того, использование strace(1) на realpath(1), чтобы понять, что он делает ...
С другой стороны, не заботиться о неканонических путях, содержащих ../
или символьных ссылок в каталогах и просто добавьте текущий каталог (см. getcwd(3)) к любому пути, не начинающемуся с /
.......
Вы должны указать более подробные сведения о том, что вы действительно хотите сделать, и дать * несколько * примеров (например, в том числе и в тех случаях, когда каталогов, указанных в пути, не существует) –
@BasileStarynkevitch: Я вполне четко объяснил, что я хочу сделать, на мой взгляд. Что нужно уточнить? –
Как вы обрабатываете '/ tmp/someinexistentdirectory/foobar' и'/tmp/someinexistentdirectory /../ foobar'? Я отказался от вашего вопроса, так как вы не сказали, как это сделать. –