【问题标题】:Regularize Non-existent path in C on Linux在 Linux 上的 C 中正则化不存在的路径
【发布时间】:2015-03-04 19:24:50
【问题描述】:

我正在为创建目录的 c 程序编写实用程序函数,但也会创建任何不存在的中间目录。我有那个代码工作,但我想把注意力转移到改进用户输入格式上。也就是说,我想在处理输入路径之前对其进行正则化,尤其是删除//,这将破坏我当前的实现。

我知道realpath(3),但我的主要问题是如果路径上的任何目录都不存在,它将失败。命令行函数realpath(1) 有-m 选项,这似乎可以满足我的要求,但如果可以避免,我不想调用shell(否则我可以执行mkdir -p 并完成它)。 Gnu findutils/canonicalize.h 有 canonicalize_filename_mode,但我不知道如何引用直接复制源代码的不足(不是不可能的)。想法、建议?

我被绑定到我的开发环境gcc 4.7.7和rhel 6.6。

下面是我当前的实现。

static int do_mkdir(const char *path, mode_t mode) {
    struct stat     st;
    int             status = 0;

    if ( stat(path, &st) != 0 ) {

       errno = 0;

        if (mkdir(path, mode) != 0 && errno != EEXIST)
            status = -1;

    } else if ( !S_ISDIR(st.st_mode) ) {
        errno = ENOTDIR;
        status = -1;
    }

    return(status);
}

int mkpath(const char *path, mode_t mode) {

    char *pp;
    char *sp;
    int   status;

    char copypath[PATH_MAX+1];
    copypath = realpath(path, copypath);

    status = 0;
    pp = copypath;

    if(copypath == NULL)
        status = -1;

    while ( status == 0 && (sp = strchr(pp, '/')) != 0 ) {

        if (sp != pp) {

            *sp = '\0';
            status = do_mkdir(copypath, mode);
            *sp = '/';

        }

        pp = sp + 1;

    }

    if ( status == 0 )
        status = do_mkdir(path, mode);

    return (status);

}

【问题讨论】:

  • findutils 和 coreutils(realpath(3) 的来源)都使用 gnulib (gnu.org/software/gnulib)。这就是canonicalize_filename_mode() 的来源。我不知道有任何方便的普通 POSIX 函数用于规范化缺少组件的路径名,因此缺少使用 gnulib 或恰好提供类似功能(或滚动您自己的)的其他库,您可能不走运。

标签: c validation path


【解决方案1】:

它可能无法完全回答您的问题,但这里有一个替代方案:

您可以使用strtok 处理path 字符串,将delim 参数设置为'/'。
通过这样做,strtok 将返回中间目录名称(空终止:您可以摆脱 \0 调整),它会优雅地忽略 //。
然后,您可以添加“清理”检查(查找无效字符、路径名太长等...)

【讨论】:

    【解决方案2】:

    我找到了一种我认为适用于所有情况的解决方法。我所做的是将对realpath 的调用移动到do_mkdir 函数中,这样它最多只有一个不存在的元素,用mkpath 函数中的strdup 替换它。我想不出在部分路径上执行规范化也会破坏任何东西的情况。

    【讨论】:

      猜你喜欢
      • 2014-02-23
      • 2015-02-19
      • 1970-01-01
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      相关资源
      最近更新 更多