realpath函数示例(C编程)

我正在寻找一个如何在C程序中使用realpath函数的示例。 我似乎无法在网上或我的任何C编程书中找到一个。

在C标准中没有描述realpath()函数。 然而,它由POSIX 1997和POSIX 2008描述。 如果这就是你的意思,这是一个例子:

 #include  /* PATH_MAX */ #include  #include  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在中定义( 来自POSIX 1997 )

单行构建命令行

极简主义,但它做的工作!

建立

 gcc -o realpath -xc - <<< $'#include\n#include\nint main(int c,char**v){puts(realpath(v[1],0));}' 

测试

 $> ./realpath ~/../../../usr/./bin/./awk /bin/gawk $> readlink -f ~/../../../usr/./bin/./awk /bin/gawk 

要求

  • gcc用于编译和链接
  • bash for <<< and $' ... \n ... '

紧急

我的极简单行命令行构建了一个可执行的实际路径,当路径不存在时会产生Segmentation fault 。 我没有在我的答案中编写if / else bloc来处理这个问题,而是在下面添加了一些链接,让你看看realpathreadlink的Busybox实现。


Busybox实现

有关更完整的源代码,请查看此简单实现。

官方Git存储库

  • coreutils/realpath.c
  • coreutils/readlink.c
  • libbb/xreadlink.c

GitHub镜像存储库

  • coreutils/realpath.c
  • coreutils/readlink.c
  • libbb/xreadlink.c

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  #include  #include  #include  #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可以在网上找到,如果你知道在哪里看。或者联系我 - 看我的个人资料。)

像这样:

 int main(int argc, char *argv[]) { ... char *symlinkpath = argv[1]; char actualpath [PATH_MAX]; char *ptr; ptr = realpath(symlinkpath, actualpath); ... } 

借来自这里