首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >'readlink -f‘的C++等效项

'readlink -f‘的C++等效项
EN

Stack Overflow用户
提问于 2014-02-05 03:18:23
回答 3查看 978关注 0票数 4

unistd.h中,我有一个C函数readlink,它跟踪一个向下的链接。coreutil readlink有一个很棒的-f选项,可以递归地跟踪每个sym链接。如何在C++中获得此行为?boost库,我不知道的posix函数,等等?

**编辑**只是查看了realpath的手册页。这给了readlink -f同样的“规范”扩展吗?

EN

回答 3

Stack Overflow用户

发布于 2016-08-09 00:00:56

是的,realpath等同于readlink -f

有关更多信息,请参阅the man page

票数 3
EN

Stack Overflow用户

发布于 2021-05-11 15:01:51

我今天确实需要这样做,建议使用realpath()失败了,因为符号链接是相对的!如果您使用的是glibc,请考虑使用canonicalize_file_name (https://man7.org/linux/man-pages/man3/canonicalize_file_name.3.html)。

当然,我在写完这段代码后就发现了这一点。我不知道这是如何跨平台的。如果您可以使用canonicalize_file_name,我不建议您使用它,但这可能是一个很好的起点:)

代码语言:javascript
复制
char *readlink_f(const char *path) {
    struct stat sb;
    char *linkname = NULL;
    ssize_t r;
    int ret = -1;
    char *ptmp = NULL;
    char *dir; // not allocated
    char *relpath = NULL;
    char *abspath = NULL;

    /* create enough space to read the link into */
    if (lstat(path, &sb) == -1) {
        fprintf(stderr, "failed to lstat the path\n");
        goto error;
    }
    linkname = malloc(sb.st_size + 1);
    if (linkname == NULL) {
        fprintf(stderr, "insufficient memory\n");
        goto error;
    }
    r = readlink(path, linkname, sb.st_size + 1);
    if (r < 0) {
        fprintf(stderr, "failed to readlink the path\n");
        goto error;
    }
    if (r > sb.st_size) {
        fprintf(stderr, "symlink increased in size between lstat() and readlink()\n");
        goto error;
    }
    linkname[sb.st_size] = '\0';

    if (linkname[0] != '/') {
        /* realpath fails with relative symlinks */
        ptmp = strdup(path); /* dirname modifies its argument */
        dir = dirname(ptmp);
        if (asprintf(&relpath, "%s/%s", dir, linkname) == -1) {
            fprintf(stderr, "failed to get generate absolute path\n");
            goto error;
        }
    } else {
        relpath = strdup(linkname);
    }

    /* canonicalize the path */
    abspath = realpath(relpath, NULL);
    if (!abspath) {
        fprintf(stderr, "failed to get canonical path\n");
        goto error;
    }

    goto cleanup;

error:
    free(abspath);
    abspath = NULL;

cleanup:
    free(linkname);
    free(ptmp);
    free(relpath);
    return abspath;
}
票数 1
EN

Stack Overflow用户

发布于 2021-11-16 15:35:18

在C++17中,您可以使用std::filesystem::canonical (如果文件不一定存在,则使用weakly_canonical )。它也是跨平台的。如果你还不能使用C++17,你仍然可以使用std::filesystem::experimental版本。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21561409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档