MCPcopy Create free account
hub / github.com/OSGeo/gdal / VSIMkdirRecursive

Function VSIMkdirRecursive

port/cpl_vsil.cpp:645–712  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

643 */
644
645int VSIMkdirRecursive(const char *pszPathname, long mode)
646{
647 if (!pszPathname)
648 return -1;
649
650 std::string osPathnameOri(pszPathname);
651 if (cpl::starts_with(osPathnameOri, "/vsimem/"))
652 {
653 osPathnameOri = VSIFileManager::GetHandler(pszPathname)
654 ->GetCanonicalFilename(osPathnameOri);
655 }
656 // Limit to avoid performance issues such as in
657 // https://issues.oss-fuzz.com/issues/471096341
658 constexpr size_t CPL_MAX_PATH = 4096;
659 if (osPathnameOri.empty() || osPathnameOri == "/" ||
660 osPathnameOri.size() > CPL_MAX_PATH)
661 return -1;
662
663 VSIStatBufL sStat;
664 if (VSIStatL(osPathnameOri.c_str(), &sStat) == 0)
665 {
666 return VSI_ISDIR(sStat.st_mode) ? 0 : -1;
667 }
668
669 std::string osCurrentPath(osPathnameOri);
670 std::vector<std::string> aosQueue;
671 while (true)
672 {
673 std::string osParentPath(CPLGetPathSafe(osCurrentPath.c_str()));
674
675 // Prevent crazy paths from recursing forever.
676 if (osParentPath.length() >= osCurrentPath.length())
677 {
678 break;
679 }
680
681 if (!osParentPath.empty() &&
682 VSIStatL(osParentPath.c_str(), &sStat) != 0)
683 {
684 osCurrentPath = std::move(osParentPath);
685 aosQueue.push_back(osCurrentPath);
686 }
687 else
688 {
689 break;
690 }
691 }
692
693 for (auto oIter = aosQueue.rbegin(); oIter != aosQueue.rend(); ++oIter)
694 {
695 if (VSIMkdir(oIter->c_str(), mode) != 0 &&
696 // In case of concurrent VSIMkdirRecursive() on the same directory
697 (VSIStatL(oIter->c_str(), &sStat) != 0 ||
698 !VSI_ISDIR(sStat.st_mode)))
699 {
700 return -1;
701 }
702 }

Callers 13

GetCurrentOutputLayerFunction · 0.85
DefaultRenameMethod · 0.85
DefaultCopyFilesMethod · 0.85
SyncMethod · 0.85
SyncMethod · 0.85
OpenMethod · 0.85
VSIFileFromMemBufferFunction · 0.85
LoadMethod · 0.85
ConvertToParquetRefMethod · 0.85
FlushDirtyBlockMethod · 0.85
FlushSingleShardMethod · 0.85
WriteChunksThreadSafeMethod · 0.85

Calls 13

VSIStatLFunction · 0.85
CPLGetPathSafeFunction · 0.85
moveFunction · 0.85
VSIMkdirFunction · 0.85
starts_withFunction · 0.70
GetCanonicalFilenameMethod · 0.45
emptyMethod · 0.45
sizeMethod · 0.45
c_strMethod · 0.45
lengthMethod · 0.45
push_backMethod · 0.45
rbeginMethod · 0.45

Tested by

no test coverage detected