獲得絕對路徑(自動擴展軟鏈接)

主要函數char* realpath(const char *path, char *resolved_path);linux

主要是想要測試下該函數自動擴展symbolic link時,最多容許symbolic link的多少層嵌套。(關鍵詞:nested symbolic links)算法

結果:在linux 2.6.21下,最多容許20層嵌套。這個嵌套深度已經足夠多了,因此,不必本身編寫得到絕對路徑的函數。直接使用該函數,而且對錯誤進行錯誤處理(而不是像示例代碼中那樣直接exit),基本上能夠知足通常的編程須要了。shell

測試以下:編程

#!/bin/bash                                                                                                                  

## generate_link file depth                                                                                                  
print_usage()
{
    echo -e "\033[40;31;1m Usage: generate_link.sh file depth \033[0m"
}

## check para num                                                                                                            
if [ $# -ne 2 ]; then
    print_usage
    exit 1
fi

file=${1}
depth=${2}

ln -s ${file} link1
for ((count=1;count<=${depth};count++)); do
    ln -s link${count} link$((count+1))
done

./generate_link.sh ../ 20bash

ls
common.h           getrealpath.c  link11  link14  link17  link2   link3  link6  link9      test
generate_link.sh   link1          link12  link15  link18  link20  link4  link7  Makefile   test.c
generate_link.sh~  link10         link13  link16  link19  link21  link5  link8  Makefile~  test.c~函數

chenqi@chenqi-laptop ~/MyPro/CFiles/detect_recursive_dir $ ./test link20
/home/chenqi/MyPro/CFiles
chenqi@chenqi-laptop ~/MyPro/CFiles/detect_recursive_dir $ ./test link21
Getting realpath of [link21] failed: Too many levels of symbolic links
測試

 

另外,之因此想到要測試下嵌套層數,是由於我想要寫個探測某目錄是否包含遞歸循環引用。這個程序自己不難,就是遍歷目錄,對三種狀況分別處理(directory, symbolic link, other)。由於遞歸循環引用只能由symbolic link,或者directory引發,因此,每次處理directory時,要記錄其絕對路徑,維護一份stack,進行入棧,出棧操做,而且在入棧時進行絕對路徑的對比;處理symbolic link時,若是其擴展後絕對路徑不是dir,確定不會引發循環引用問題,若是是dir,則處理該dir。好比:spa

dir1 = {link1, file1, file2, ..., filen}code

dir2 = {link2, file1, file2, ..., filen}遞歸

link1 -> dir2; link2 -> dir1

因而遍歷dir1時,有以下計算順序:

處理dir1,dir1是一個目錄,因此入棧,從此,若是再有元素入棧,而該元素的路徑是dir1或者dir1的父路徑,則出現遞歸循環引用。

處理link1,link1是一個symbolic link,得到其絕對路徑dir2.

處理dir2,dir2是一個目錄,因此入棧。dir2不是dir1,也不是dir1的父路徑。

處理link2,link2是一個sym link,得到其絕對路徑dir1.

處理dir1,目錄,入棧。dir1是棧中元素dir1,因此出現遞歸循環引用。記錄,輸出。

處理dir2中的file2.....

dir2處理完成,dir2出棧。

處理dir1中的file2等

整體來講,處理目錄之初進棧,而且判斷,處理完目錄出棧;處理sym link時,若是其絕對路徑是dir,則處理該dir。

因此,如上所述,該算法中有兩個關鍵的subroutine,一個是得到絕對路徑。一個是判斷某目錄是不是另一個目錄或者其父目錄

如上測試,realpath能解析20層的symbolic link嵌套,絕對知足要求。

代碼以下:

#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        assert(argc == 2);
        const char *filepath = argv[1];
        char *real_path = realpath(filepath, NULL);
        if (real_path == NULL)  /* failed */
        {
                fprintf(stderr, "Getting realpath of [%s] failed: %s \n",
                        filepath, strerror(errno));
                exit(EXIT_FAILURE);
        }
        else                    /* succeed */
        {
                printf("%s\n", real_path);
                free(real_path);
        }
        exit(EXIT_SUCCESS);
}
相關文章
相關標籤/搜索