C ++ 17 या उसके बाद के, <filesystem>
फ़ंक्शन के साथ मानक हेडर है
std::filesystem::create_directories
जिसे आधुनिक C ++ प्रोग्राम में उपयोग किया जाना चाहिए। C ++ मानक फ़ंक्शंस में POSIX- विशिष्ट स्पष्ट अनुमतियाँ (मोड) तर्क नहीं है, हालांकि।
हालाँकि, यहाँ एक C फ़ंक्शन है जिसे C ++ कंपाइलर के साथ संकलित किया जा सकता है।
/*
@(#)File: mkpath.c
@(#)Purpose: Create all directories in path
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 1990-2020
@(#)Derivation: mkpath.c 1.16 2020/06/19 15:08:10
*/
/*TABSTOP=4*/
#include "posixver.h"
#include "mkpath.h"
#include "emalloc.h"
#include <errno.h>
#include <string.h>
/* "sysstat.h" == <sys/stat.h> with fixup for (old) Windows - inc mode_t */
#include "sysstat.h"
typedef struct stat Stat;
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 <stdio.h>
#include <unistd.h>
/*
** 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()
और FREE()
की त्रुटि की जाँच संस्करण हैं
strdup()
और free()
, में घोषित emalloc.h
(और कार्यान्वित में
emalloc.c
और estrdup.c
)। "sysstat.h"
की टूट संस्करणों के साथ शीर्ष लेख सौदों <sys/stat.h>
और द्वारा बदला जा सकता है <sys/stat.h>
आधुनिक यूनिक्स प्रणालियों पर (लेकिन कई मुद्दों 1990 में वापस वहाँ थे)। और "mkpath.h"
घोषित करता है mkpath()
।
V1.12 (उत्तर के मूल संस्करण) और v1.13 (उत्तर की संशोधित संस्करण) के बीच बदलाव के लिए परीक्षण किया गया था EEXIST
में
do_mkdir()
। यह स्विच द्वारा आवश्यक के रूप में बताया गया था
- धन्यवाद, स्विच। मैकबुक प्रो (2.3GHz Intel Core i7, Mac OS X 10.7.4 पर चल रहा है) पर परीक्षण कोड को समस्या को उन्नत और पुन: पेश किया गया है, और सुझाव देता है कि समस्या संशोधन में तय की गई है (लेकिन परीक्षण केवल बग की उपस्थिति दिखा सकता है , उनकी अनुपस्थिति कभी नहीं)। दिखाया गया कोड अब v1.16 है; v1.13 के बाद से कॉस्मेटिक या प्रशासनिक परिवर्तन किए गए हैं (जैसे कि mkpath.h
इसके बजाय उपयोग jlss.h
और <unistd.h>
केवल परीक्षण कोड में बिना शर्त शामिल हैं )। यह तर्क "sysstat.h"
देना उचित है कि <sys/stat.h>
जब तक आपके पास असामान्य रूप से पुनर्गणना प्रणाली नहीं होती है, तब तक इसे बदल दिया जाना चाहिए
।
(आप एट्रिब्यूशन के साथ किसी भी उद्देश्य के लिए इस कोड का उपयोग करने की अनुमति दी गई है।)
यह कोड मेरे SOQ
(स्टैक ओवरफ्लो प्रश्न) GitHub पर फाइलों mkpath.c
और
mkpath.h
(आदि)
src / so-0067-5039
उप-निर्देशिका में उपलब्ध है।