89 lines
3.9 KiB
C
89 lines
3.9 KiB
C
/* Небольшие файловые/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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#include <direct.h>
|
|
|
|
// Временный путь текущей единицы трансляции; успешный 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 <unistd.h>
|
|
|
|
// Создать каталог по 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
|