300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > linux中创建目录树 如何在C++/Linux中创建目录树?

linux中创建目录树 如何在C++/Linux中创建目录树?

时间:2023-12-31 14:02:37

相关推荐

linux中创建目录树 如何在C++/Linux中创建目录树?

Jonathan Lef..

58

这是一个可以用C++编译器编译的C函数.

/*

@(#)File: $RCSfile: mkpath.c,v $

@(#)Version: $Revision: 1.13 $

@(#)Last changed: $Date: /07/15 00:40:37 $

@(#)Purpose: Create all directories in path

@(#)Author: J Leffler

@(#)Copyright: (C) JLSS 1990-91,1997-98,2001,,,

*/

/*TABSTOP=4*/

#include "jlss.h"

#include "emalloc.h"

#include

#ifdef HAVE_UNISTD_H

#include

#endif /* HAVE_UNISTD_H */

#include

#include "sysstat.h" /* Fix up for Windows - inc mode_t */

typedef struct stat Stat;

#ifndef lint

/* Prevent over-aggressive optimizers from eliminating ID string */

const char jlss_id_mkpath_c[] = "@(#)$Id: mkpath.c,v 1.13 /07/15 00:40:37 jleffler Exp $";

#endif /* lint */

static int do_mkdir(const char *path, mode_t mode)

{

Stat st;

int status = 0;

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

{

/* Directory does not exist. EEXIST for race condition */

if (mkdir(path, mode) != 0 && errno != EEXIST)

status = -1;

}

else if (!S_ISDIR(st.st_mode))

{

errno = ENOTDIR;

status = -1;

}

return(status);

}

/**

** mkpath - ensure all directories in path exist

** Algorithm takes the pessimistic view and works top-down to ensure

** each directory in path exists, rather than optimistically creating

** the last element and working backwards.

*/

int mkpath(const char *path, mode_t mode)

{

char *pp;

char *sp;

int status;

char *copypath = STRDUP(path);

status = 0;

pp = copypath;

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

{

if (sp != pp)

{

/* Neither root nor double slash in path */

*sp = '\0';

status = do_mkdir(copypath, mode);

*sp = '/';

}

pp = sp + 1;

}

if (status == 0)

status = do_mkdir(path, mode);

FREE(copypath);

return (status);

}

#ifdef TEST

#include

/*

** Stress test with parallel running of mkpath() function.

** Before the EEXIST test, code would fail.

** With the EEXIST test, code does not fail.

**

** Test shell script

** PREFIX=mkpath.$$

** NAME=./$PREFIX/sa/32/ad/13/23/13/12/13/sd/ds/ww/qq/ss/dd/zz/xx/dd/rr/ff/ff/ss/ss/ss/ss/ss/ss/ss/ss

** : ${MKPATH:=mkpath}

** ./$MKPATH $NAME &

** [...repeat a dozen times or so...]

** ./$MKPATH $NAME &

** wait

** rm -fr ./$PREFIX/

*/

int main(int argc, char **argv)

{

int i;

for (i = 1; i < argc; i++)

{

for (int j = 0; j < 20; j++)

{

if (fork() == 0)

{

int rc = mkpath(argv[i], 0777);

if (rc != 0)

fprintf(stderr, "%d: failed to create (%d: %s): %s\n",

(int)getpid(), errno, strerror(errno), argv[i]);

exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);

}

}

int status;

int fail = 0;

while (wait(&status) != -1)

{

if (WEXITSTATUS(status) != 0)

fail = 1;

}

if (fail == 0)

printf("created: %s\n", argv[i]);

}

return(0);

}

#endif /* TEST */

这些宏是STRDUP()and FREE()的错误检查版本,strdup()并free()在emalloc.h(并在emalloc.c和中实现estrdup.c)声明.该"sysstat.h"用的破碎版本头交易,并且可以被替换为现代Unix系统上(但在1990年出现了许多问题后).并"jlss.h"宣布mkpath().

v1.12(上一个)和v1.13(上面)之间的变化是EEXISTin 的测试do_mkdir().Switch指出这是必要的- 谢谢你,Switch.测试代码已经升级并在MacBook Pro(2.3GHz Intel Core i7,运行Mac OS X 10.7.4)上重现了问题,并建议在修订版中修复问题(但测试只能显示错误的存在) ,从不他们缺席).

(特此允许您将此代码用于任何归属目的.)

这个代码中有一个微妙的竞争条件,我实际上已经击中了.它只发生在多个程序同时启动并生成相同的文件夹路径时.修复是添加`if(errno!= EEXIST){status = -1; 当mkdir失败时. (7认同)

它肯定比系统更快.系统涉及很多开销.基本上,进程必须分叉,然后必须至少加载两个二进制文件(一个可能已经在缓存中),其中另一个是另一个的另一个分支,... (2认同)

@Switch:谢谢.这是在`mkdir()`之前使用`stat()`的麻烦; 这是TOCTOU(检查时间,使用时间)问题.我尝试使用在后台运行13个进程的shell脚本来创建相同的29个元素的路径,并且无法点击它.然后我把测试程序分成20次,让每个孩子尝试,然后设法击中了这个bug.固定代码将具有`if(mkdir(path,mode)!= 0 && errno!= EEXIST)status = -1;`.这没有显示错误. (2认同)

@DavidMerinos:它们是头文件(jlss.h,emalloc.h),而不是库。但是,该代码在GitHub上的[SOQ](/jleffler/soq)(堆栈溢出问题)存储库中可用,分别为文件`jlss.h`,`emalloc.c`和`emalloc.h。在[src / libsoq](/jleffler/soq/tree/master/src/libsoq)子目录中。您还需要`posixver.h`,以及其他一些(`debug.h`,`stderr.c`,`stderr.h-我想就是这样,但是您所需要的都应该在该目录中) 。 (2认同)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。