【发布时间】: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