/* Небольшие файловые/env helpers тестов POSIX/Windows; возврат 0 — успех, -1 либо код CRT — ошибка. * Созданными каталогами/файлами владеет caller: cleanup выполняется явно, автоматического удаления нет. * POSIX mkdtemp требует writable шаблон с конечными XXXXXX. Windows игнорирует шаблон и возвращает путь в TEMP: * буфер caller должен вмещать MAX_PATH, для переносимого кода передавать ненулевой буфер не меньше этого размера. * Windows использует общие rand/srand и статический буфер в каждой единице трансляции; параллельные вызовы не поддерживаются. */ #ifndef TEST_UTILS_H #define TEST_UTILS_H #include "../lib/platform_compat.h" #include #include #include #ifdef _WIN32 #include #include // Временный путь текущей единицы трансляции; успешный test_mkdtemp копирует его в буфер caller. static char test_temp_dir[MAX_PATH]; // До 100 попыток создать TEMP/utun_test_XXXXXXXX; 0 — создан (путь копируется при template_str!=NULL), -1 — отказ. static inline int test_mkdtemp(char *template_str) { char tmp_path[MAX_PATH]; GetTempPathA(MAX_PATH, tmp_path); // Generate unique directory name srand((unsigned int)GetTickCount()); int attempts = 0; while (attempts < 100) { snprintf(test_temp_dir, sizeof(test_temp_dir), "%s\\utun_test_%08x", tmp_path, (unsigned int)rand()); if (_mkdir(test_temp_dir) == 0) { // Copy path back to caller's buffer if provided if (template_str) { size_t len = strlen(test_temp_dir); memcpy(template_str, test_temp_dir, len + 1); // Include null terminator } return 0; // Success } attempts++; } return -1; // Failed after 100 attempts } // Изменить CRT _environ, видимый getenv; overwrite=0 сохраняет существующую переменную. Возврат — _putenv_s. static inline int test_setenv(const char *name, const char *value, int overwrite) { if (!overwrite && getenv(name)) return 0; return _putenv_s(name, value); /* 0 = success, errno_t != 0 = error */ } // Удалить один файл (не дерево каталогов), возврат _unlink: 0/-1. static inline int test_unlink(const char *path) { return _unlink(path); } // Удалить пустой каталог, возврат _rmdir: 0/-1. static inline int test_rmdir(const char *path) { return _rmdir(path); } #else // POSIX: helpers делегируют штатным API; errno остаётся у вызывающего. #include // Создать каталог по mutable шаблону XXXXXX и записать путь в тот же буфер; 0/-1. static inline int test_mkdtemp(char *template_str) { return (mkdtemp(template_str) == NULL) ? -1 : 0; } // Изменить environment через setenv; overwrite=0 сохраняет существующее значение, возврат 0/-1. static inline int test_setenv(const char *name, const char *value, int overwrite) { return setenv(name, value, overwrite); } // Удалить один файл/симлинк через unlink, не рекурсивно; 0/-1. static inline int test_unlink(const char *path) { return unlink(path); } // Удалить пустой каталог через rmdir; 0/-1. static inline int test_rmdir(const char *path) { return rmdir(path); } #endif #endif // TEST_UTILS_H