void Helpers::CreateTTDDirectoryAsNeeded(size_t* uriLength, char* uri, const char* asciiDir1, const wchar* asciiDir2) { if(*uriLength + strlen(asciiDir1) + wcslen(asciiDir2) + 2 > MAX_URI_LENGTH || strlen(asciiDir1) >= MAX_TTD_ASCII_PATH_EXT_LENGTH || wcslen(asciiDir2) >= MAX_TTD_ASCII_PATH_EXT_LENGTH) { wprintf(_u("We assume bounded MAX_URI_LENGTH for simplicity.\n")); wprintf(_u("%S, %S, %ls\n"), uri, asciiDir1, asciiDir2); exit(1); } int success = 0; int extLength = 0; extLength = sprintf_s(uri + *uriLength, MAX_TTD_ASCII_PATH_EXT_LENGTH, "%s%s", asciiDir1, TTD_HOST_PATH_SEP); if(extLength == -1 || MAX_URI_LENGTH < (*uriLength) + extLength) { wprintf(_u("Failed directory extension 1.\n")); wprintf(_u("%S, %S, %ls\n"), uri, asciiDir1, asciiDir2); exit(1); } *uriLength += extLength; success = TTDHostMKDir(uri, *uriLength); if(success != 0) { //we may fail because someone else created the directory -- that is ok Helpers::TTReportLastIOErrorAsNeeded(errno == EEXIST, "Failed to create directory"); } char realAsciiDir2[MAX_TTD_ASCII_PATH_EXT_LENGTH]; size_t asciiDir2Length = wcslen(asciiDir2) + 1; for(size_t i = 0; i < asciiDir2Length; ++i) { if(asciiDir2[i] > CHAR_MAX) { wprintf(_u("Test directory names can only include ascii chars.\n")); exit(1); } realAsciiDir2[i] = (char)asciiDir2[i]; } extLength = sprintf_s(uri + *uriLength, MAX_TTD_ASCII_PATH_EXT_LENGTH, "%s%s", realAsciiDir2, TTD_HOST_PATH_SEP); if(extLength == -1 || MAX_URI_LENGTH < *uriLength + extLength) { wprintf(_u("Failed directory create 2.\n")); wprintf(_u("%S, %S, %ls\n"), uri, asciiDir1, asciiDir2); exit(1); } *uriLength += extLength; success = TTDHostMKDir(uri, *uriLength); if(success != 0) { //we may fail because someone else created the directory -- that is ok Helpers::TTReportLastIOErrorAsNeeded(errno == EEXIST, "Failed to create directory"); } }
void Helpers::CreateDirectoryIfNeeded(size_t uriByteLength, const byte* uriBytes) { TTDHostCharType opath[MAX_PATH]; TTDHostInitFromUriBytes(opath, uriBytes, uriByteLength); TTDHostCharType cpath[MAX_PATH]; TTDHostInitEmpty(cpath); TTDDoPathInit(cpath); TTDHostStatType statVal; TTDHostCharType* context = nullptr; TTDHostCharType* token = TTDHostTok(opath, TTDHostPathSeparator, &context); TTDHostAppend(cpath, token); //At least 1 part of the path must exist so iterate until we find it while(TTDHostStat(cpath, &statVal) == -1) { token = TTDHostTok(nullptr, TTDHostPathSeparator, &context); TTDHostAppend(cpath, TTDHostPathSeparator); TTDHostAppend(cpath, token); } //Now continue until we hit the part that doesn't exist (or the end of the path) while(token != nullptr && TTDHostStat(cpath, &statVal) != -1) { token = TTDHostTok(nullptr, TTDHostPathSeparator, &context); if(token != nullptr) { TTDHostAppend(cpath, TTDHostPathSeparator); TTDHostAppend(cpath, token); } } //Now if there is path left then continue build up the directory tree as we go while(token != nullptr) { int success = TTDHostMKDir(cpath); if(success != 0) { //we may fail because someone else created the directory -- that is ok Helpers::TTReportLastIOErrorAsNeeded(errno != ENOENT, "Failed to create directory"); } token = TTDHostTok(nullptr, TTDHostPathSeparator, &context); if(token != nullptr) { TTDHostAppend(cpath, TTDHostPathSeparator); TTDHostAppend(cpath, token); } } }