Files
utun2/lib/file_io.h
T

45 lines
3.8 KiB
C

/* file_io — синхронные файловые операции для workers: UTF-8 пути, идентичность и публикация через соседний temp.
* inspect: 0 найден, 1 отсутствует, -1 ошибка; остальные операции 0/-1, paths также 1 для одного файла.
* Temp обнулить → open → писать в file → finish → publish; discard обязателен также при ошибке.
* Исходник и каталоги должны оставаться стабильными на время операции. Это не защита от подмены родительских каталогов.
* Publish заменяет имя атомарно, но не обещает сохранность при аварии питания. POSIX temp имеет права 0600. */
#ifndef FILE_IO_H
#define FILE_IO_H
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#define FILE_IO_PATH_MAX 4096
enum file_io_type { FILE_IO_REGULAR = 1, FILE_IO_DIRECTORY, FILE_IO_LINK, FILE_IO_OTHER };
struct file_io_info {
int type; // обычный файл, каталог, ссылка/reparse point или другой объект
int64_t size; // размер в байтах, без сужения до int
uint64_t identity[3]; // идентификатор файла внутри файловой системы, сравнивать весь массив
};
struct file_io_temp {
char temporary[FILE_IO_PATH_MAX]; // только собственный temp; пусто после discard/publish
FILE *file; // открытый wb+; NULL после finish
};
// path — UTF-8; follow!=0 разрешает конечную ссылку. info обязателен, заполняется только при успехе.
int file_io_inspect(const char *path, int follow, struct file_io_info *info);
#ifdef _WIN32
// Преобразовать непустой UTF-8 путь в wide[FILE_IO_PATH_MAX]; 0/-1.
int file_io_wide(const char *path, wchar_t wide[FILE_IO_PATH_MAX]);
#endif
// Открыть обычный файл для чтения; путь UTF-8. NULL при ошибке, fclose принадлежит вызывающему.
FILE *file_io_open_read(const char *path);
// Открыть существующий regular-файл для чтения/записи без усечения; конечные ссылки запрещены. UTF-8, NULL при ошибке.
FILE *file_io_open_update(const char *path);
// Источник должен быть regular; назначение отсутствует или regular без конечной ссылки. 1 — один файл, 0 — разные, -1 — ошибка.
int file_io_paths(const char *source, const char *destination);
// Создать эксклюзивный temp рядом с destination; структура заранее обнулена, даже после ошибки вызвать discard.
int file_io_temp_open(struct file_io_temp *output, const char *destination);
// Проверить flush/close, обнулить file при любом результате; temp остаётся собственностью output.
int file_io_temp_finish(struct file_io_temp *output);
// Закрыть/удалить собственный temp; повторный вызов допустим. Ошибки очистки логируются.
void file_io_temp_discard(struct file_io_temp *output);
// Повторно проверить paths и заменить destination закрытым temp; одинаковые файлы отклоняются.
int file_io_temp_publish(struct file_io_temp *output, const char *source, const char *destination);
#endif