Jonathan Lef..

58

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

/*

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

@(#)Version: $Revision: 1.13 $

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

@(#)Purpose: Create all directories in path

@(#)Author: J Leffler

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

*/

/*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 2012/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](https://github.com/jleffler/soq)(堆栈溢出问题)存储库中可用,分别为文件`jlss.h`,`emalloc.c`和`emalloc.h。在[src / libsoq](https://github.com/jleffler/soq/tree/master/src/libsoq)子目录中。您还需要`posixver.h`,以及其他一些(`debug.h`,`stderr.c`,`stderr.h-我想就是这样,但是您所需要的都应该在该目录中) 。 (2认同)

linux中创建目录树,如何在C++/Linux中创建目录树?相关推荐

  1. linux卸载欧朋浏览器,如何在Ubuntu系统中安装和卸载Opera浏览器

    以下内容教您如何在Ubuntu操作系统中安装Opera浏览器. 通常,可以通过以下方法安装不同的Opera版本. 下面将向您展示如何在Ubuntu中安装Opera 55版本的浏览器. 如果不需要,则可 ...

  2. linux终端密码星星,如何在Ubuntu终端中显示密码星号

    每当要求您在Ubuntu终端中键入密码时,都将插入密码,而不会得到任何可视显示或屏幕反馈.在这种情况下,您可能会通过错误输入密码而弄乱密码.这就是视觉反馈如此重要的原因.它可以帮助您跟踪输入的字符数, ...

  3. linux kvm百度云,如何在 Ubuntu Linux 上使用 KVM 云镜像

    如何下载并使用运行在 Ubuntu Linux 服务器上的 KVM 云镜像?如何在 Ubuntu Linux 16.04 LTS 服务器上无需完整安装即可创建虚拟机?如何在 Ubuntu Linux ...

  4. 在html表格中进行计算,如何在word表格中实现计算功能?超级实用,值得细细品味...

    常听同事们说:word就是文字处理,excel就是制表计算.乍一听,也没什么不妥啊,但细细一想,这是对word很大的伤害. 今天得改改这种看法了,其实,word表格也有计算功能,例如:在财务报表.工资 ...

  5. lsdyna如何设置set中的node_list_如何在Matlab GUI中播放带声音的视频?

    各位同学好,各位知乎的小伙伴们大家好.今天,我要给大家分享的内容是:"如何在Matlab GUI中播放带声音的视频?" 这个问题有点奇怪,什么叫做带声音的视频?视频一般不都是带声音 ...

  6. linux中创建目录树,如何在C/Linux中创建目录树?

    这里有一个C函数可以用C编译器编译. /* @(#)File: $RCSfile: mkpath.c,v $ @(#)Version: $Revision: 1.13 $ @(#)Last chang ...

  7. linux mint 安装内核,如何在Ubuntu, Linux Mint中安装Linux Kernel 4.18

    Linus Torvalds终于在12日下午宣布发布Linux Kernel 4.18. 他在lkml.org写道: 这是一个非常平静的一周,可以说我上周可以按时发布,但我们确实有一些小的更新. 主要 ...

  8. win10 linux分区大小调整大小,如何在windows系统中调整分区大小(包括windows10/8/7)...

    对磁盘进行分区(尤其是Windows 10,8和7)至关重要.毕竟,通过磁盘的分区,任务和其他程序的处理可以采用更有效的路线.分区可以更轻松地整理任务并专注于重要的事情. 分区磁盘时,第一次尝试时总是 ...

  9. linux gradle仓库位置,如何在Android Studio中使用Gradle发布项目至Jcenter仓库

    简述 目前非常流行将开源库上传至Jcenter仓库中,使用起来非常方便且易于维护,特别是在Android Studio环境中,只需几步配置就可以轻松实现上传和发布. Library的转换和引用 博主的 ...

最新文章

  1. c语言一个偶数用两个素数表示,用java怎样编写一个偶数总能表示为两个素数之和的程序...
  2. View Horizon Mirage安装手册(一)——Horizon Mirage介绍
  3. 字符串类String
  4. html5 video js控制摄像头的焦距,html 通过input video canvas 打开摄像头 定制相机
  5. 【短信插件】短信如何对接74cms_v4.2.66_骑士人才系统
  6. 数据仓库专题(6)-数据仓库、主题域、主题概念与定义
  7. Python之数据分析(动画效果、animation模块、气泡动画)
  8. java io类filereader,39. Java IO: FileReader
  9. Java 8 流API(Stream)介绍与示例
  10. 小波变换和motion信号处理(二)
  11. 在vc++如何响应键盘和鼠标事件-visual c++
  12. vbs脚本打开web窗口隐藏地址栏和工具栏
  13. 小觅相机运行VINS-Fusion(二)——Camera-IMU参数标定
  14. Js、Jquery对goTop功能的实现
  15. 禁用浏览器的后退按钮
  16. 风湿与类风湿的关系以及风湿病涉及基因突变与基因甲基化的文献收集(仍在更新。。。)
  17. tilemap 导入unity_Unity3D中Isometric Tilemap功能实践
  18. 卡尔曼滤波/粒子滤波融合定位模拟器
  19. android stuio修改代码参考线和智能换行
  20. mmc子系统分析(一)

热门文章

  1. springboot中获取bean_最新Spring Boot干货总结(超详细,建议收藏)
  2. Scrum之 回顾会议
  3. wince Hive注册表实现机制
  4. 【转】WPF XAML X名称空间详解
  5. 【转】.NET 自带的动态代理+Expression 实现AOP
  6. 【转】c#中@的3种作用
  7. C++11 FAQ中文版:std::function 和 std::bind
  8. java 实现真正的随机数_关于java:SecureRandom的Android实现是否产生真正的随机数?...
  9. java引入resource下的模板_Beetl自定义ResourceLoader,实现特殊的模板加载需求
  10. 字节流转化为文件流_字节流转成字符串之后,在通过字符串转成字节流后的文件为什么会不一样?...