我正在寻找一个如何在C程序中使用realpath函数的示例。我似乎无法在网上或我的任何C编程书中找到一个。
答案 0 :(得分:20)
C标准中未描述realpath()
功能。然而,它由POSIX 1997和POSIX 2008描述。如果这就是你的意思,这是一个例子:
#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char buf[PATH_MAX + 1]; /* not sure about the "+ 1" */
char *res = realpath("this_source.c", buf);
if (res) {
printf("This source is at %s.\n", buf);
} else {
perror("realpath");
exit(EXIT_FAILURE);
}
return 0;
}
PATH_MAX在<limits.h>(<limits.h> from POSIX 1997)
中定义答案 1 :(得分:4)
极简主义,但它确实起作用了!
<强>构建强>
gcc -o realpath -x c - <<< $'#include<stdlib.h>\n#include<stdio.h>\nint main(int c,char**v){puts(realpath(v[1],0));}'
<强>测试强>
$> ./realpath ~/../../../usr/./bin/./awk
/bin/gawk
$> readlink -f ~/../../../usr/./bin/./awk
/bin/gawk
<强>要求强>
<强>崩溃强>
我的极简单行命令行构建了一个可执行文件realpath
,当路径不存在时会产生Segmentation fault
。我没有在我的回答中编写if
/ else
块来处理该问题,而是在下面添加了一些链接,让您了解realpath
和{{1}的Busybox实现}。
有关更完整的源代码,请查看这个简单的实现。
官方Git存储库
GitHub镜像存储库
答案 2 :(得分:3)
realpath()
函数的作用是在解析所有符号链接后告诉您文件的路径名。如果您提供的值是相对名称,则不一定是绝对路径名,但这部分取决于您是否遍历具有链接值的绝对名称的任何符号链接 - 如果这样做,那么输出毕竟是绝对名称。此外,如果相对名称遍历到根目录(或“超出”,如'../../../../../ ..',当目录层次结构中只有三个级别时)。
您的计算机上可能已有“realpath”程序。这是我写的(非标准)版本。
/*
@(#)File: $RCSfile: realpath.c,v $
@(#)Version: $Revision: 1.3 $
@(#)Last changed: $Date: 2007/10/23 20:23:44 $
@(#)Purpose: Command to evaluate realpath(3) on given arguments.
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 2007
@(#)Product: :PRODUCT:
*/
/*TABSTOP=4*/
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif /* __STDC_VERSION__ */
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include "stderr.h"
static const char optstr[] = "hlsV";
static const char usestr[] = "[-hslV] given-path [...]";
static const char hlpstr[] =
" -h Print this help message\n"
" -l Long format: print given-path and real-path\n"
" -s Short format: print just real-path\n"
" -V Print version and exit\n"
;
enum { FMT_LONG, FMT_SHORT };
static int format_type = FMT_LONG;
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
extern const char jlss_id_realpath_c[];
const char jlss_id_realpath_c[] = "@(#)$Id: realpath.c,v 1.3 2007/10/23 20:23:44 jleffler Exp $";
#endif /* lint */
static int eval_realpath(const char *given)
{
char realname[_POSIX_PATH_MAX];
int rc = 0;
if (realpath(given, realname) == 0)
{
rc = -1;
err_sysrem("failed to resolve real path name for %s\n", given);
}
else if (format_type == FMT_SHORT)
printf("%s\n", realname);
else
printf("%s %s\n", given, realname);
return(rc);
}
int main(int argc, char **argv)
{
int i;
int rc = EXIT_SUCCESS;
int opt;
err_setarg0(argv[0]);
while ((opt = getopt(argc, argv, optstr)) != -1)
{
switch (opt)
{
case 'V':
err_version("REALPATH", &"@(#)$Revision: 1.3 $ ($Date: 2007/10/23 20:23:44 $)"[4]);
break;
case 'h':
err_help(usestr, hlpstr);
break;
case 'l':
format_type = FMT_LONG;
break;
case 's':
format_type = FMT_SHORT;
break;
default:
err_usage(usestr);
break;
}
}
for (i = optind; i < argc; i++)
{
if (eval_realpath(argv[i]) != 0)
rc = EXIT_FAILURE;
}
return(rc);
}
我需要它来测试一些评估路径安全性的软件,并且需要确保我的代码正在评估与realpath()
相同的解析位置的给定路径。使用'-a'选项扩展它可能是明智的,以确保名称映射到绝对名称(通过将getcwd()
的结果加前缀到相对路径名)。
(stderr.c的来源,stderr.h可以在网上找到,如果你知道在哪里看。或者联系我 - 看我的个人资料。)
答案 3 :(得分:0)
像这样:
int main(int argc, char *argv[]) {
...
char *symlinkpath = argv[1];
char actualpath [PATH_MAX];
char *ptr;
ptr = realpath(symlinkpath, actualpath);
...
}
借鉴here