Generalise the file rotating logic
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
// Generated by the DN single header generator 2026-07-16 14:16:33
|
// Generated by the DN single header generator 2026-07-16 23:31:53
|
||||||
|
|
||||||
// DN: Single header generator commented out => #if defined(_CLANGD)
|
// DN: Single header generator commented out => #if defined(_CLANGD)
|
||||||
// #define DN_WITH_TESTS 1
|
// #define DN_WITH_TESTS 1
|
||||||
@@ -11592,16 +11592,6 @@ DN_API void DN_OS_LogPrintF(DN_LogTypeParam type, void *user_data, DN_CallSite c
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath(DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index)
|
|
||||||
{
|
|
||||||
DN_Str8 result = {};
|
|
||||||
if (rotate_index == 0)
|
|
||||||
result = DN_OS_PathFmtArena(arena, "%.*s", DN_Str8PrintFmt(base_file_path));
|
|
||||||
else
|
|
||||||
result = DN_OS_PathFmtArena(arena, "%.*s.%zu", DN_Str8PrintFmt(base_file_path), rotate_index);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
||||||
{
|
{
|
||||||
if (logger->file_path.data) {
|
if (logger->file_path.data) {
|
||||||
@@ -11649,15 +11639,7 @@ static void DN_OS_DoLogFileSetupAndRotation_(DN_OSLogger *logger)
|
|||||||
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
|
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
|
||||||
if (needs_rotate) {
|
if (needs_rotate) {
|
||||||
DN_OS_FileClose(&logger->file);
|
DN_OS_FileClose(&logger->file);
|
||||||
// NOTE: Loop through all the rotated log files from [rotate_count-1..1]. The rotated log
|
DN_OS_FileRotate(logger->file_path, logger->rotate_count, DN_Str8Lit("."), DN_OSFileRotateFlags_Nil);
|
||||||
// file at `rotate_count-1` gets deleted and `rotate_count-2` gets moved into
|
|
||||||
// `rotate_count-1` and so forth
|
|
||||||
for (DN_USize offset = 0; offset < (logger->rotate_count - 1); offset++) {
|
|
||||||
DN_USize const file_index = logger->rotate_count - (offset + 1);
|
|
||||||
DN_Str8 file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index);
|
|
||||||
DN_Str8 prev_file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index - 1);
|
|
||||||
DN_OS_FileMove(prev_file_path, file_path, true, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: After rotating, check the file size of the log file we will write to again. If the
|
// NOTE: After rotating, check the file size of the log file we will write to again. If the
|
||||||
@@ -11967,11 +11949,45 @@ DN_API uint64_t DN_OS_EstimateTSCPerSecond(uint64_t duration_ms_to_gauge_tsc_fre
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_PathIsOlderThan(DN_Str8 path, DN_Str8 check_against)
|
DN_API bool DN_OS_FileRotate(DN_Str8 base_file_path, DN_USize rotate_count, DN_Str8 suffix, DN_OSFileRotateFlags flags)
|
||||||
{
|
{
|
||||||
DN_OSPathInfo file_info = DN_OS_PathInfo(path);
|
// NOTE: Loop through all the rotated files from [rotate_count-1..0]. The rotated file at
|
||||||
DN_OSPathInfo check_against_info = DN_OS_PathInfo(check_against);
|
// `rotate_count-1` (if it exists) gets deleted and `rotate_count-2` gets moved into
|
||||||
bool result = !file_info.exists || file_info.last_write_time_in_s < check_against_info.last_write_time_in_s;
|
// `rotate_count-1` and so forth.
|
||||||
|
bool result = true;
|
||||||
|
if (rotate_count) {
|
||||||
|
if (rotate_count == 1) {
|
||||||
|
// NOTE: Rotate count of 1 just means that the base file should be deleted essentially unless
|
||||||
|
// the keep base flag is set.
|
||||||
|
if (DN_BitIsNotSet(flags, DN_OSFileRotateFlags_KeepBaseFile))
|
||||||
|
DN_OS_PathDelete(base_file_path);
|
||||||
|
} else {
|
||||||
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
|
for (DN_USize offset = 0; offset < (rotate_count - 1); offset++) {
|
||||||
|
DN_USize const file_index = rotate_count - (offset + 1);
|
||||||
|
bool last_file_index = file_index - 1 == 0;
|
||||||
|
DN_AssertF(file_index != 0, "This index should never hits zero, we iterate in reverse and stop 1 before the last one");
|
||||||
|
|
||||||
|
DN_Str8 file_path = DN_Str8FromFmtArena(&scratch.arena, "%.*s%.*s%zu", DN_Str8PrintFmt(base_file_path), DN_Str8PrintFmt(suffix), file_index);
|
||||||
|
DN_Str8 prev_file_path = last_file_index ? base_file_path : DN_Str8FromFmtArena(&scratch.arena, "%.*s%.*s%zu", DN_Str8PrintFmt(base_file_path), DN_Str8PrintFmt(suffix), file_index - 1);
|
||||||
|
DN_OSPathInfo file_path_info = DN_OS_PathInfo(file_path);
|
||||||
|
DN_OSPathInfo prev_file_path_info = DN_OS_PathInfo(prev_file_path);
|
||||||
|
|
||||||
|
if (file_path_info.type == DN_OSPathInfoType_Directory || prev_file_path_info.type == DN_OSPathInfoType_Directory) {
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_file_path_info.exists) {
|
||||||
|
if (last_file_index && (flags & DN_OSFileRotateFlags_KeepBaseFile))
|
||||||
|
result &= DN_OS_FileCopy(prev_file_path, file_path, /*overwrite=*/true, nullptr);
|
||||||
|
else
|
||||||
|
result &= DN_OS_FileMove(prev_file_path, file_path, /*overwrite=*/true, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DN_TCScratchEnd(&scratch);
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12162,6 +12178,14 @@ DN_API DN_Str8 DN_OS_Str8FromPathInfoType(DN_OSPathInfoType type)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN_API bool DN_OS_PathIsOlderThan(DN_Str8 path, DN_Str8 check_against)
|
||||||
|
{
|
||||||
|
DN_OSPathInfo file_info = DN_OS_PathInfo(path);
|
||||||
|
DN_OSPathInfo check_against_info = DN_OS_PathInfo(check_against);
|
||||||
|
bool result = !file_info.exists || file_info.last_write_time_in_s < check_against_info.last_write_time_in_s;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
|
DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
|
||||||
{
|
{
|
||||||
if (!arena || !fs_path || path.count == 0)
|
if (!arena || !fs_path || path.count == 0)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by the DN single header generator 2026-07-16 14:16:33
|
// Generated by the DN single header generator 2026-07-16 23:31:53
|
||||||
|
|
||||||
#if !defined(DN_H)
|
#if !defined(DN_H)
|
||||||
#define DN_H
|
#define DN_H
|
||||||
@@ -4216,7 +4216,18 @@ struct DN_OSTimer /// Record time between two time-points using the OS's perform
|
|||||||
DN_U64 end;
|
DN_U64 end;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: DN_OSFile
|
typedef DN_U32 DN_OSFileRotateFlags;
|
||||||
|
enum DN_OSFileRotateFlags_
|
||||||
|
{
|
||||||
|
DN_OSFileRotateFlags_Nil = 0,
|
||||||
|
|
||||||
|
// NOTE: All files are rotated as usual but when it's time to rotate the base file to index 1,
|
||||||
|
// this flags causes the base file to be copied to index 1 instead of being moved. This may be
|
||||||
|
// useful if you are looking to make rotating backups rather than rotating files.
|
||||||
|
DN_OSFileRotateFlags_KeepBaseFile = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum DN_OSPathInfoType
|
enum DN_OSPathInfoType
|
||||||
{
|
{
|
||||||
DN_OSPathInfoType_Unknown,
|
DN_OSPathInfoType_Unknown,
|
||||||
@@ -6458,19 +6469,13 @@ DN_API void DN_OS_SetLogPrintFuncToOS
|
|||||||
// `DN_OSLoggerFlags_FileError` from the logger before attempting to log again. Setting a new
|
// `DN_OSLoggerFlags_FileError` from the logger before attempting to log again. Setting a new
|
||||||
// file path via `DN_OS_LoggerSetFilePath` will also clear this flag.
|
// file path via `DN_OS_LoggerSetFilePath` will also clear this flag.
|
||||||
//
|
//
|
||||||
// The rotating logger outputs files to the base `file_path` and then rotates it to
|
// See `DN_OS_FileRotate` for more information on the rotating scheme. The files are rotated with
|
||||||
// `<file_path>.1` after the desired size is rotated for example:
|
// a suffix of ".".
|
||||||
//
|
|
||||||
// <file_path>
|
|
||||||
// <file_path>.1
|
|
||||||
// ..
|
|
||||||
// <file_path>.N-1
|
|
||||||
//
|
//
|
||||||
// The target byte count for rotation is a hint. A large log message on a file teetering against
|
// The target byte count for rotation is a hint. A large log message on a file teetering against
|
||||||
// the maximum allowed byte size will cause the log file to exceed the target size before being
|
// the maximum allowed byte size will cause the log file to exceed the target size before being
|
||||||
// rotated on the next log invocation.
|
// rotated on the next log invocation.
|
||||||
|
|
||||||
DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath (DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index);
|
|
||||||
DN_API void DN_OS_LoggerSetFilePath (DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path);
|
DN_API void DN_OS_LoggerSetFilePath (DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path);
|
||||||
DN_API void DN_OS_LoggerFV (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args);
|
DN_API void DN_OS_LoggerFV (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||||
DN_API void DN_OS_LoggerF (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...);
|
DN_API void DN_OS_LoggerF (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...);
|
||||||
@@ -6548,8 +6553,46 @@ DN_API DN_F64 DN_OS_TimerUs (D
|
|||||||
DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer);
|
DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer);
|
||||||
DN_API DN_U64 DN_OS_EstimateTSCPerSecond (uint64_t duration_ms_to_gauge_tsc_frequency);
|
DN_API DN_U64 DN_OS_EstimateTSCPerSecond (uint64_t duration_ms_to_gauge_tsc_frequency);
|
||||||
|
|
||||||
|
// NOTE: OS File
|
||||||
|
// Overview
|
||||||
|
// File system manipulation functionality. Implemented using Win32 API and POSIX API on linux
|
||||||
|
// machines.
|
||||||
|
|
||||||
|
// API
|
||||||
|
// DN_OS_FileRotate
|
||||||
|
// Rotate the file at `base_file_path` by moving it to `<base_file_path><suffix><rotate_index>`
|
||||||
|
// and then moving the file at `rotate_index+1` to `rotate_index+2` up until `rotate_count`.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// base_file_path: "log.txt"
|
||||||
|
// rotate_count: 4
|
||||||
|
// suffix: ".bak."
|
||||||
|
//
|
||||||
|
// Will execute the rotate operation, in this order:
|
||||||
|
//
|
||||||
|
// log.txt.bak.2 moves to => log.txt.bak.3
|
||||||
|
// log.txt.bak.1 moves to => log.txt.bak.2
|
||||||
|
// log.txt moves to => log.txt.bak.1
|
||||||
|
//
|
||||||
|
// Set the flag `DN_OSFileRotateFlags_KeepBaseFile` to preserve the `base_file_path` by copying
|
||||||
|
// it instead of moving it, e.g the example changes to:
|
||||||
|
//
|
||||||
|
// log.txt.bak.2 moves to => log.txt.bak.3
|
||||||
|
// log.txt.bak.1 moves to => log.txt.bak.2
|
||||||
|
// log.txt copied to => log.txt.bak.1
|
||||||
|
//
|
||||||
|
// This function is a no-op if `rotate_count <= 0`. If `rotate_count == 1` we interpret that as
|
||||||
|
// we want to cycle the singular file specified at `base_file_path` which translates to just
|
||||||
|
// deleting the file specified at `base_file_path` unless `DN_OSFileRotateFlags_KeepBaseFile`
|
||||||
|
// is set. In that case this function also becomes a no-op.
|
||||||
|
//
|
||||||
|
// If any of the files to rotate are directories this function will stop and return false. If
|
||||||
|
// the files to rotate does not exist, the function returns true.
|
||||||
|
|
||||||
DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
||||||
DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
||||||
|
DN_API bool DN_OS_FileRotate (DN_Str8 base_file_path, DN_USize rotate_count, DN_Str8 suffix, DN_OSFileRotateFlags flags);
|
||||||
|
|
||||||
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_ErrSink *err);
|
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_ErrSink *err);
|
||||||
DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize count, DN_ErrSink *err);
|
DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize count, DN_ErrSink *err);
|
||||||
|
|||||||
+47
-23
@@ -11590,16 +11590,6 @@ DN_API void DN_OS_LogPrintF(DN_LogTypeParam type, void *user_data, DN_CallSite c
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath(DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index)
|
|
||||||
{
|
|
||||||
DN_Str8 result = {};
|
|
||||||
if (rotate_index == 0)
|
|
||||||
result = DN_OS_PathFmtArena(arena, "%.*s", DN_Str8PrintFmt(base_file_path));
|
|
||||||
else
|
|
||||||
result = DN_OS_PathFmtArena(arena, "%.*s.%zu", DN_Str8PrintFmt(base_file_path), rotate_index);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
||||||
{
|
{
|
||||||
if (logger->file_path.data) {
|
if (logger->file_path.data) {
|
||||||
@@ -11647,15 +11637,7 @@ static void DN_OS_DoLogFileSetupAndRotation_(DN_OSLogger *logger)
|
|||||||
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
|
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
|
||||||
if (needs_rotate) {
|
if (needs_rotate) {
|
||||||
DN_OS_FileClose(&logger->file);
|
DN_OS_FileClose(&logger->file);
|
||||||
// NOTE: Loop through all the rotated log files from [rotate_count-1..1]. The rotated log
|
DN_OS_FileRotate(logger->file_path, logger->rotate_count, DN_Str8Lit("."), DN_OSFileRotateFlags_Nil);
|
||||||
// file at `rotate_count-1` gets deleted and `rotate_count-2` gets moved into
|
|
||||||
// `rotate_count-1` and so forth
|
|
||||||
for (DN_USize offset = 0; offset < (logger->rotate_count - 1); offset++) {
|
|
||||||
DN_USize const file_index = logger->rotate_count - (offset + 1);
|
|
||||||
DN_Str8 file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index);
|
|
||||||
DN_Str8 prev_file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index - 1);
|
|
||||||
DN_OS_FileMove(prev_file_path, file_path, true, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: After rotating, check the file size of the log file we will write to again. If the
|
// NOTE: After rotating, check the file size of the log file we will write to again. If the
|
||||||
@@ -11965,11 +11947,45 @@ DN_API uint64_t DN_OS_EstimateTSCPerSecond(uint64_t duration_ms_to_gauge_tsc_fre
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_PathIsOlderThan(DN_Str8 path, DN_Str8 check_against)
|
DN_API bool DN_OS_FileRotate(DN_Str8 base_file_path, DN_USize rotate_count, DN_Str8 suffix, DN_OSFileRotateFlags flags)
|
||||||
{
|
{
|
||||||
DN_OSPathInfo file_info = DN_OS_PathInfo(path);
|
// NOTE: Loop through all the rotated files from [rotate_count-1..0]. The rotated file at
|
||||||
DN_OSPathInfo check_against_info = DN_OS_PathInfo(check_against);
|
// `rotate_count-1` (if it exists) gets deleted and `rotate_count-2` gets moved into
|
||||||
bool result = !file_info.exists || file_info.last_write_time_in_s < check_against_info.last_write_time_in_s;
|
// `rotate_count-1` and so forth.
|
||||||
|
bool result = true;
|
||||||
|
if (rotate_count) {
|
||||||
|
if (rotate_count == 1) {
|
||||||
|
// NOTE: Rotate count of 1 just means that the base file should be deleted essentially unless
|
||||||
|
// the keep base flag is set.
|
||||||
|
if (DN_BitIsNotSet(flags, DN_OSFileRotateFlags_KeepBaseFile))
|
||||||
|
DN_OS_PathDelete(base_file_path);
|
||||||
|
} else {
|
||||||
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
|
for (DN_USize offset = 0; offset < (rotate_count - 1); offset++) {
|
||||||
|
DN_USize const file_index = rotate_count - (offset + 1);
|
||||||
|
bool last_file_index = file_index - 1 == 0;
|
||||||
|
DN_AssertF(file_index != 0, "This index should never hits zero, we iterate in reverse and stop 1 before the last one");
|
||||||
|
|
||||||
|
DN_Str8 file_path = DN_Str8FromFmtArena(&scratch.arena, "%.*s%.*s%zu", DN_Str8PrintFmt(base_file_path), DN_Str8PrintFmt(suffix), file_index);
|
||||||
|
DN_Str8 prev_file_path = last_file_index ? base_file_path : DN_Str8FromFmtArena(&scratch.arena, "%.*s%.*s%zu", DN_Str8PrintFmt(base_file_path), DN_Str8PrintFmt(suffix), file_index - 1);
|
||||||
|
DN_OSPathInfo file_path_info = DN_OS_PathInfo(file_path);
|
||||||
|
DN_OSPathInfo prev_file_path_info = DN_OS_PathInfo(prev_file_path);
|
||||||
|
|
||||||
|
if (file_path_info.type == DN_OSPathInfoType_Directory || prev_file_path_info.type == DN_OSPathInfoType_Directory) {
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_file_path_info.exists) {
|
||||||
|
if (last_file_index && (flags & DN_OSFileRotateFlags_KeepBaseFile))
|
||||||
|
result &= DN_OS_FileCopy(prev_file_path, file_path, /*overwrite=*/true, nullptr);
|
||||||
|
else
|
||||||
|
result &= DN_OS_FileMove(prev_file_path, file_path, /*overwrite=*/true, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DN_TCScratchEnd(&scratch);
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12160,6 +12176,14 @@ DN_API DN_Str8 DN_OS_Str8FromPathInfoType(DN_OSPathInfoType type)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN_API bool DN_OS_PathIsOlderThan(DN_Str8 path, DN_Str8 check_against)
|
||||||
|
{
|
||||||
|
DN_OSPathInfo file_info = DN_OS_PathInfo(path);
|
||||||
|
DN_OSPathInfo check_against_info = DN_OS_PathInfo(check_against);
|
||||||
|
bool result = !file_info.exists || file_info.last_write_time_in_s < check_against_info.last_write_time_in_s;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
|
DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
|
||||||
{
|
{
|
||||||
if (!arena || !fs_path || path.count == 0)
|
if (!arena || !fs_path || path.count == 0)
|
||||||
|
|||||||
+52
-9
@@ -2286,7 +2286,18 @@ struct DN_OSTimer /// Record time between two time-points using the OS's perform
|
|||||||
DN_U64 end;
|
DN_U64 end;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: DN_OSFile
|
typedef DN_U32 DN_OSFileRotateFlags;
|
||||||
|
enum DN_OSFileRotateFlags_
|
||||||
|
{
|
||||||
|
DN_OSFileRotateFlags_Nil = 0,
|
||||||
|
|
||||||
|
// NOTE: All files are rotated as usual but when it's time to rotate the base file to index 1,
|
||||||
|
// this flags causes the base file to be copied to index 1 instead of being moved. This may be
|
||||||
|
// useful if you are looking to make rotating backups rather than rotating files.
|
||||||
|
DN_OSFileRotateFlags_KeepBaseFile = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum DN_OSPathInfoType
|
enum DN_OSPathInfoType
|
||||||
{
|
{
|
||||||
DN_OSPathInfoType_Unknown,
|
DN_OSPathInfoType_Unknown,
|
||||||
@@ -4528,19 +4539,13 @@ DN_API void DN_OS_SetLogPrintFuncToOS
|
|||||||
// `DN_OSLoggerFlags_FileError` from the logger before attempting to log again. Setting a new
|
// `DN_OSLoggerFlags_FileError` from the logger before attempting to log again. Setting a new
|
||||||
// file path via `DN_OS_LoggerSetFilePath` will also clear this flag.
|
// file path via `DN_OS_LoggerSetFilePath` will also clear this flag.
|
||||||
//
|
//
|
||||||
// The rotating logger outputs files to the base `file_path` and then rotates it to
|
// See `DN_OS_FileRotate` for more information on the rotating scheme. The files are rotated with
|
||||||
// `<file_path>.1` after the desired size is rotated for example:
|
// a suffix of ".".
|
||||||
//
|
|
||||||
// <file_path>
|
|
||||||
// <file_path>.1
|
|
||||||
// ..
|
|
||||||
// <file_path>.N-1
|
|
||||||
//
|
//
|
||||||
// The target byte count for rotation is a hint. A large log message on a file teetering against
|
// The target byte count for rotation is a hint. A large log message on a file teetering against
|
||||||
// the maximum allowed byte size will cause the log file to exceed the target size before being
|
// the maximum allowed byte size will cause the log file to exceed the target size before being
|
||||||
// rotated on the next log invocation.
|
// rotated on the next log invocation.
|
||||||
|
|
||||||
DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath (DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index);
|
|
||||||
DN_API void DN_OS_LoggerSetFilePath (DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path);
|
DN_API void DN_OS_LoggerSetFilePath (DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path);
|
||||||
DN_API void DN_OS_LoggerFV (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args);
|
DN_API void DN_OS_LoggerFV (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||||
DN_API void DN_OS_LoggerF (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...);
|
DN_API void DN_OS_LoggerF (DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...);
|
||||||
@@ -4618,8 +4623,46 @@ DN_API DN_F64 DN_OS_TimerUs (D
|
|||||||
DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer);
|
DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer);
|
||||||
DN_API DN_U64 DN_OS_EstimateTSCPerSecond (uint64_t duration_ms_to_gauge_tsc_frequency);
|
DN_API DN_U64 DN_OS_EstimateTSCPerSecond (uint64_t duration_ms_to_gauge_tsc_frequency);
|
||||||
|
|
||||||
|
// NOTE: OS File
|
||||||
|
// Overview
|
||||||
|
// File system manipulation functionality. Implemented using Win32 API and POSIX API on linux
|
||||||
|
// machines.
|
||||||
|
|
||||||
|
// API
|
||||||
|
// DN_OS_FileRotate
|
||||||
|
// Rotate the file at `base_file_path` by moving it to `<base_file_path><suffix><rotate_index>`
|
||||||
|
// and then moving the file at `rotate_index+1` to `rotate_index+2` up until `rotate_count`.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// base_file_path: "log.txt"
|
||||||
|
// rotate_count: 4
|
||||||
|
// suffix: ".bak."
|
||||||
|
//
|
||||||
|
// Will execute the rotate operation, in this order:
|
||||||
|
//
|
||||||
|
// log.txt.bak.2 moves to => log.txt.bak.3
|
||||||
|
// log.txt.bak.1 moves to => log.txt.bak.2
|
||||||
|
// log.txt moves to => log.txt.bak.1
|
||||||
|
//
|
||||||
|
// Set the flag `DN_OSFileRotateFlags_KeepBaseFile` to preserve the `base_file_path` by copying
|
||||||
|
// it instead of moving it, e.g the example changes to:
|
||||||
|
//
|
||||||
|
// log.txt.bak.2 moves to => log.txt.bak.3
|
||||||
|
// log.txt.bak.1 moves to => log.txt.bak.2
|
||||||
|
// log.txt copied to => log.txt.bak.1
|
||||||
|
//
|
||||||
|
// This function is a no-op if `rotate_count <= 0`. If `rotate_count == 1` we interpret that as
|
||||||
|
// we want to cycle the singular file specified at `base_file_path` which translates to just
|
||||||
|
// deleting the file specified at `base_file_path` unless `DN_OSFileRotateFlags_KeepBaseFile`
|
||||||
|
// is set. In that case this function also becomes a no-op.
|
||||||
|
//
|
||||||
|
// If any of the files to rotate are directories this function will stop and return false. If
|
||||||
|
// the files to rotate does not exist, the function returns true.
|
||||||
|
|
||||||
DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
||||||
DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err);
|
||||||
|
DN_API bool DN_OS_FileRotate (DN_Str8 base_file_path, DN_USize rotate_count, DN_Str8 suffix, DN_OSFileRotateFlags flags);
|
||||||
|
|
||||||
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_ErrSink *err);
|
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_ErrSink *err);
|
||||||
DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize count, DN_ErrSink *err);
|
DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize count, DN_ErrSink *err);
|
||||||
|
|||||||
Reference in New Issue
Block a user