一、realpath函数概述
realpath函数是一个Unix或类Unix操作系统上经常用到的函数,它可以返回给定路径的绝对路径,即去除所有./和../符号,并将符号连接解析为其值。如果路径不存在,realpath函数将返回NULL,并将errno设置为ENOENT。
realpath函数的语法如下:
char *realpath(const char *path, char *resolved_path);
其中,path指向要解析的路径名,resolved_path是指用来存放解析后的路径名的缓冲区。如果resolved_path为NULL,则函数会自动分配缓冲区并在函数结束时释放该缓冲区。
二、realpath函数使用示例
下面是一个简单的示例程序,以演示如何使用realpath函数。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s pathn", argv[0]);
return EXIT_FAILURE;
}
char *resolved_path = NULL;
resolved_path = realpath(argv[1], resolved_path);
if (resolved_path == NULL) {
perror("realpath");
return EXIT_FAILURE;
}
printf("The real path of %s is %sn", argv[1], resolved_path);
free(resolved_path);
return EXIT_SUCCESS;
}
该程序接受一个命令行参数,即为要解析的路径名。程序中通过调用realpath函数解析指定的路径,并将解析后的路径打印到控制台上。
三、realpath函数详解
1. 返回值和错误处理
realpath函数的返回值为解析后的路径名,如果出错则返回NULL。
如果出错,realpath函数会设置errno为以下错误代码之一:
- ENOENT:路径不存在
- EACCES:没有足够的权限
- ENOMEM:内存不足
2. 第二个参数
realpath函数的第二个参数是一个指针,用于存放解析后的路径名。如果该参数为NULL,则会自动为解析后的路径名分配内存。
如果指定了该参数,resolved_path必须指向一个能够容纳解析后的路径名的缓冲区,并且必须大于或等于PATH_MAX个字节。如果resolved_path不大于PATH_MAX个字节,则可能会截断解析后的路径名。
在成功调用realpath函数后,如果指定了该参数,返回的路径名与resolved_path相同;如果resolved_path为NULL,则自动分配的缓冲区会在函数结束时释放。
以下是一个示例程序,演示如何使用指定的缓冲区来存放解析后的路径名:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s pathn", argv[0]);
return EXIT_FAILURE;
}
char resolved_path[PATH_MAX];
if (realpath(argv[1], resolved_path) == NULL) {
perror("realpath");
return EXIT_FAILURE;
}
printf("The real path of %s is %sn", argv[1], resolved_path);
return EXIT_SUCCESS;
}
3. 关于符号链接
realpath函数会解析所有符号链接,直到找到一个存在的文件或一次解析出错,然后返回解析后的路径名。如果无法解析符号链接(例如符号链接的目标不存在),则realpath函数会返回NULL,并将errno设置为ENOTDIR。
以下是一个演示符号链接解析的示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>>
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s pathn", argv[0]);
return EXIT_FAILURE;
}
char *resolved_path = NULL;
resolved_path = realpath(argv[1], resolved_path);
if (resolved_path == NULL) {
perror("realpath");
return EXIT_FAILURE;
}
printf("The real path of %s is %sn", argv[1], resolved_path);
// create a symbolic link
if (symlink(resolved_path, "foo") == -1) {
perror("symlink");
return EXIT_FAILURE;
}
// resolve the symbolic link
char link_path[PATH_MAX];
if (realpath("foo", link_path) == NULL) {
perror("realpath");
return EXIT_FAILURE;
}
printf("The real path of the symlink is %sn", link_path);
free(resolved_path);
return EXIT_SUCCESS;
}
该程序首先使用realpath函数解析指定路径,然后创建一个名为foo的符号链接。程序接着使用realpath函数解析foo链接,并将结果打印到控制台上。
4. 关于奇怪的路径名
realpath函数也可以解析一些奇怪的路径名,例如“/dev/stdin”和“/proc/self/exe”等。下面是一个演示的示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>>
#include <linux/limits.h>
int main() {
char buf[PATH_MAX] = {0};
// resolve /dev/stdin
realpath("/dev/stdin", buf);
printf("/dev/stdin: %sn", buf);
// resolve /proc/self/exe
realpath("/proc/self/exe", buf);
printf("/proc/self/exe: %sn", buf);
return 0;
}
四、结论
realpath函数是一个非常有用的函数,可以将相对路径名解析为绝对路径名,并且可以解析所有符号链接。希望本文能够对你理解realpath函数有所帮助。