realpath()库函数对pathname中的所有符合链接一一解引用,从而成功一个以空字符结尾的字符串,内涵相应的绝对路径名:

NAME
       realpath - 返回规范化的绝对路径名 

SYNOPSIS
       #include <limits.h>
       #include <stdlib.h>

       char *realpath(const char *path, char *resolved_path);

描述
        realpath()扩展所有符号链接,并解析对以path命名的以null终止的字符串中的/.//../和
        其他“ /”字符的引用,以产生规范化的绝对路径名。 生成的路径名将以一个以空字符结尾的字符串
        存储(最多PATH_MAX个字节),存储在由resolve_path指向的缓冲区中。 结果路径将没有符号
        链接,///../组件。

        如果将resolve_path指定为NULL,则realpath()使用malloc(3)分配最多PATH_MAX字节
        的缓冲区以保存已解析的路径名,并返回指向该缓冲区的指针。 调用者应使用free(3)释放此缓冲区。 

RETURN VALUE
       如果没有错误,则realpath()返回指向resolve_path的指针。

        否则,它将返回NULL指针,未定义数组resolve_path的内容,并且设置了errno来指示错误。 

生成的字符串将置于resolved_path指向的缓冲区中,该字符串是一个字符数组,长度至少是PATH_MAX个字节。一旦调用成功,readpath()将返回一个指向该字符串的一个指针。

glibc的realpath()实现允许调用者将resolved_path参数指定为NULL,这时,realpath()将结果分配到一个最多PATH_MAX字节 的缓冲区中,并将指向该缓冲区的指针作为结果返回(调用者必须自行调用free()来释放该缓冲区)。SUSv3 并未将该扩展功能纳入规范,但SUSv4 对其进行了定义

下面程序中采用 readlink()和 realpath()来读取符号链接的内容,并将该链接解析为一个绝对路径名

#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <zconf.h>

#define BUF_SIZE PATH_MAX
int
main(int argc, char *argv[])
{
    struct stat statbuf;
    char buf[BUF_SIZE];
    ssize_t numBytes;

    if (argc != 2 || strcmp(argv[1], "--help") == 0){
        printf("%s pathname\n", argv[0]);
        exit(EXIT_FAILURE);
    }


    /* User lstat() to check whether the supplied pathname is
       a symbolic link. Alternatively, we could have checked to
       whether readlink() failed with EINVAL. */

    if (lstat(argv[1], &statbuf) == -1) {
        perror("lstat");
        exit(EXIT_FAILURE);
    }

    if (!S_ISLNK(statbuf.st_mode)){
        printf("%s is not a symbolic link", argv[1]);
        exit(EXIT_FAILURE);
    }


    numBytes = readlink(argv[1], buf, BUF_SIZE - 1);
    if (numBytes == -1){
        perror("readlink");
        exit(EXIT_FAILURE);
    }

    buf[numBytes] = '\0';                       /* Add terminating null byte */
    printf("readlink: %s --> %s\n", argv[1], buf);

    if (realpath(argv[1], buf) == NULL){
        perror("realpath");
        exit(EXIT_FAILURE);
    }

    printf("realpath: %s --> %s\n", argv[1], buf);

    exit(EXIT_SUCCESS);
}

在这里插入图片描述

Logo

更多推荐