C语言中的realpath函数示例

C语言中的realpath函数示例,c,posix,realpath,gcc,bash,C,Posix,Realpath,Gcc,Bash,我正在寻找一个如何在C程序中使用realpath函数的示例。我似乎在web上或我的任何C编程书籍中都找不到。C标准中没有描述realpath()函数。然而,和对其进行了描述。如果这就是你的意思,下面是一个例子: #include <limits.h> /* PATH_MAX */ #include <stdio.h> #include <stdlib.h> int main(void) { char buf[PATH_MAX]; /* PATH_MAX

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

C标准中没有描述
realpath()
函数。然而,和对其进行了描述。如果这就是你的意思,下面是一个例子:

#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char buf[PATH_MAX]; /* PATH_MAX incudes the \0 so +1 is not required */
    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;
}
\include/*PATH\u MAX*/
#包括
#包括
内部主(空){
char buf[PATH_MAX];/*PATH_MAX包含\0,因此不需要+1*/
char*res=realpath(“this_source.c”,buf);
如果(res){
printf(“此源位于%s.\n”,buf);
}否则{
perror(“realpath”);
退出(退出失败);
}
返回0;
}
路径MAX在()中定义如下:

int main(int argc, char *argv[]) {
    ...
    char *symlinkpath = argv[1];
    char actualpath [PATH_MAX];
    char *ptr;
    ptr = realpath(symlinkpath, actualpath);
    ...
}
借用自的
realpath()
函数的作用是在解析所有符号链接后告诉您文件的路径名。如果您提供的值是相对名称,则不一定是绝对路径名,但这部分取决于您是否使用链接值的绝对名称遍历任何符号链接-如果是,则输出毕竟是绝对名称。此外,如果相对名称一直延伸到根目录(或“beyond”,如“../../../../../../../....”,而在目录层次结构中只有三个级别)

您的计算机上可能已经有“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);
}
/*
@(#)文件:$RCSfile:realpath.c,v$
@(#)版本:$修订版:1.3$
@(#)上次更改:$日期:2007/10/23 20:23:44$
@(#)用途:在给定参数上计算realpath(3)的命令。
@(#)作者:J Leffler
@(#)版权所有:(C)JLSS 2007
@(#)产品::产品:
*/
/*TABSTOP=4*/
#如果STDC版本=199901L
#定义_XOPEN_源600
#否则
#定义_XOPEN_源500
#endif/*\uuuu STDC\u版本\uuuu*/
#包括
#包括
#包括
#包括
#包括“stderr.h”
静态常量char optstr[]=“hlsV”;
静态常量char usestr[]=“[-hslV]给定路径[…]”;
静态常量字符hlpstr[]=
“-h打印此帮助消息\n”
“-l长格式:打印给定路径和实际路径\n”
“-s短格式:仅打印真实路径\n”
“-V打印版本并退出\n”
;
枚举{FMT_LONG,FMT_SHORT};
静态整数格式\u类型=FMT\u LONG;
#ifndef皮棉
/*防止过度激进的优化器消除ID字符串*/
外部常量字符jlss_id_realpath_c[];
const char jlss_id_realpath_c[]=“@(#)$id:realpath.c,v1.3 2007/10/23 20:23:44 jleffler Exp$”;
#endif/*lint*/
静态int eval_realpath(常量字符*给定)
{
char realname[_POSIX_PATH_MAX];
int rc=0;
if(realpath(给定,realname)==0)
{
rc=-1;
err_sysrem(“无法解析%s的实际路径名,\n”,给定);
}
else if(格式类型==FMT\U SHORT)
printf(“%s\n”,realname);
其他的
printf(“%s%s\n”,给定,实名);
返回(rc);
}
int main(int argc,字符**argv)
{
int i;
int rc=退出成功;
int-opt;
err_setarg0(argv[0]);
while((opt=getopt(argc、argv、optstr))!=-1)
{
开关(opt)
{
案例“V”:
err_版本(“REALPATH”和“@(#)$修订版:1.3$($日期:2007/10/23 20:23:44$)”[4]);
打破
案例“h”:
错误帮助(usestr、hlpstr);
打破
案例“l”:
格式类型=FMT\u LONG;
打破
案例s:
格式类型=FMT\U SHORT;
打破
违约:
错误用法(usestr);
打破
}
}
对于(i=optind;i
我需要它来测试一些正在评估路径安全性的软件,并且需要确保我的代码正在评估给定路径到与
realpath()
相同的解析位置。使用“-a”选项对其进行扩展可能是明智的,以确保名称映射到绝对名称(通过将
getcwd()的结果前缀为相对路径名)

(如果您知道在哪里查找,可以在线找到stderr.c、stderr.h的源代码。或者与我联系-查看我的个人资料。)

One-line build命令行 极简主义者,但它做到了

构建

gcc -o realpath -x c - <<< $'#include<stdlib.h>\n#include<stdio.h>\nint main(int c,char**v){puts(realpath(v[1],0));}'
要求

  • 用于编辑和链接

  • 对于
    PATH\u MAX是路径的最大长度。这是一个奇怪的小发明;保证有一个值_POSIX_PATH_MAX,它是PATH_MAX可能的最小值。但是,许多系统的
    没有设置PATH_MAX,这意味着机器上的路径最大长度没有规定的限制。无论如何,它也可能依赖于文件系统。因此,您可以使用sysconf()或pathconf()查找一个值,或者您可以猜测大多数正常人使用的路径长度不超过1024字节,并使用该值realpath
    并从
    res
    完成后,执行code>。As
    realpath
    在堆中分配返回值。来源:
    manrealpath
    @JalalMostafa:POSIX
    realpath()
    ,如我回答中的链接所述,不分配内存。我怀疑您的系统不符合POSIX标准。对第二个参数调用符合POSIX规范的
    realpath()
    时使用
    NULL
    调用UB。@JalalMostafa:有一个新版本的POSIX规范(),其中第二个参数可以为NULL,然后调用
    malloc()
    。在我的示例中,缓冲区是一个本地数组,因此没有理由调用
    free()
    。感谢您的提醒。
    PATH\u MAX
    中的
    +1
    可能是用于
    \0
    的。不,它一定会给您一个绝对路径名。说“realpath()函数应该从file_name指向的路径名派生出一个命名相同文件的绝对路径名,…”,这很奇怪;你是
    $> ./realpath  ~/../../../usr/./bin/./awk
    /bin/gawk 
    
    $> readlink -f ~/../../../usr/./bin/./awk
    /bin/gawk