Add comprehensive README covering architecture, API usage, build instructions, tested drivers, binary patching details, and DGROUP layout. Expand file header comments in all library sources and headers to document module responsibilities, data flow, and key constraints. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
89 lines
1.6 KiB
C
89 lines
1.6 KiB
C
// ============================================================================
|
|
// log.c - Logging to file
|
|
//
|
|
// Simple dual-output logger: messages go to a log file (opened by
|
|
// logInit) and optionally to stdout (logMsg) or stderr (logErr).
|
|
// An optional pre-I/O hook is called before every write, used by
|
|
// windrv.c to ensure the S3 engine is idle before file I/O (DOSBox-X
|
|
// processes S3 operations during file writes).
|
|
// ============================================================================
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
|
|
#include "log.h"
|
|
|
|
static FILE *gLogFile = NULL;
|
|
static LogPreIoFuncT gPreIoHook = NULL;
|
|
|
|
|
|
void logInit(const char *filename)
|
|
{
|
|
if (filename) {
|
|
gLogFile = fopen(filename, "w");
|
|
}
|
|
}
|
|
|
|
|
|
void logErr(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
logErrV(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
|
|
void logErrV(const char *fmt, va_list ap)
|
|
{
|
|
if (gLogFile) {
|
|
if (gPreIoHook) {
|
|
gPreIoHook();
|
|
}
|
|
vfprintf(gLogFile, fmt, ap);
|
|
fflush(gLogFile);
|
|
}
|
|
}
|
|
|
|
|
|
FILE *logGetFile(void)
|
|
{
|
|
return gLogFile;
|
|
}
|
|
|
|
|
|
void logMsg(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
logMsgV(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
|
|
void logMsgV(const char *fmt, va_list ap)
|
|
{
|
|
if (gLogFile) {
|
|
if (gPreIoHook) {
|
|
gPreIoHook();
|
|
}
|
|
vfprintf(gLogFile, fmt, ap);
|
|
fflush(gLogFile);
|
|
}
|
|
}
|
|
|
|
|
|
void logSetPreIoHook(LogPreIoFuncT func)
|
|
{
|
|
gPreIoHook = func;
|
|
}
|
|
|
|
|
|
void logShutdown(void)
|
|
{
|
|
if (gLogFile) {
|
|
fflush(gLogFile);
|
|
fclose(gLogFile);
|
|
gLogFile = NULL;
|
|
}
|
|
}
|