realpath() without resolving symlinks?

后端 未结 3 1725
粉色の甜心
粉色の甜心 2020-12-10 14:03

I already read about realpath(), but is there a function that I can pass a base directory and a filename that would give me the following result without resolvi

3条回答
  •  半阙折子戏
    2020-12-10 14:45

    I use Hardex's solution:

    #include 
    
    char * normalizePath(char* pwd, const char * src, char* res) {
        size_t res_len;
        size_t src_len = strlen(src);
    
        const char * ptr = src;
        const char * end = &src[src_len];
        const char * next;
    
        if (src_len == 0 || src[0] != '/') {
            // relative path
            size_t pwd_len;
    
            pwd_len = strlen(pwd);
            memcpy(res, pwd, pwd_len);
            res_len = pwd_len;
        } else {
            res_len = 0;
        }
    
        for (ptr = src; ptr < end; ptr=next+1) {
            size_t len;
            next = (char*)memchr(ptr, '/', end-ptr);
            if (next == NULL) {
                next = end;
            }
            len = next-ptr;
            switch(len) {
            case 2:
                if (ptr[0] == '.' && ptr[1] == '.') {
                    const char * slash = (char*)memrchr(res, '/', res_len);
                    if (slash != NULL) {
                        res_len = slash - res;
                    }
                    continue;
                }
                break;
            case 1:
                if (ptr[0] == '.') {
                    continue;
                }
                break;
            case 0:
                continue;
            }
    
            if (res_len != 1)
                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;
    }
    

    Example:

    #include 
    
    int main(){
        char path[FILENAME_MAX+1];
        printf("\n%s\n",normalizePath((char*)"/usr/share/local/apps",(char*)"./../../../",path));
        return 0;
    }
    

    Output:

    /usr
    


    Note:

    1. The first argument is the directory path (absolute path) relative to which other paths will be normalized. It is generally the absolute path of the current directory.
    2. The second argument is the string to be normalized without resolving symlinks.
    3. The third argument is a char* which must have the required memory/capacity to contain the normalized path.

提交回复
热议问题