26static char *errcopy = NULL;
28static size_t moutcopy;
29static size_t merrcopy;
31static int noutcopy = 0;
32static int nerrcopy = 0;
36static char *errfiledouble = NULL;
39static int copying = 0;
42static PHYSFS_File *logout_file = NULL;
43static PHYSFS_File *logerr_file = NULL;
49static void log_append( FILE *stream,
char *str );
50static void log_cleanStream( PHYSFS_File **file,
const char *fname,
const char *filedouble );
56int logprintf( FILE *stream,
int newline,
const char *fmt, ... )
64 n = vsnprintf( NULL, 0, fmt, ap );
66 buf = malloc( 2+n+2 );
68 n = vsnprintf( &buf[2], n + 1, fmt, ap );
83 if (stream == stdout && logout_file != NULL) {
84 PHYSFS_writeBytes( logout_file, &buf[2], newline ? n+1 : n );
86 PHYSFS_flush( logout_file );
89 if (stream == stderr && logerr_file != NULL) {
90 PHYSFS_writeBytes( logerr_file, &buf[2], newline ? n+1 : n );
92 PHYSFS_flush( logerr_file );
96 n = fprintf( stream,
"%s", &buf[ 2 ] );
118 ts = localtime(&cur);
119 strftime( timestr,
sizeof(timestr),
"%Y-%m-%d_%H-%M-%S", ts );
121 PHYSFS_mkdir(
"logs" );
122 logout_file = PHYSFS_openWrite(
"logs/stdout.txt" );
123 if ( logout_file == NULL )
124 WARN(_(
"Unable to redirect stdout to file"));
126 logerr_file = PHYSFS_openWrite(
"logs/stderr.txt" );
127 if ( logerr_file == NULL )
128 WARN(_(
"Unable to redirect stderr to file"));
130 SDL_asprintf( &
outfiledouble,
"logs/%s_stdout.txt", timestr );
131 SDL_asprintf( &errfiledouble,
"logs/%s_stderr.txt", timestr );
159 if (copying == enable)
167 outcopy = calloc(moutcopy, BUFSIZ);
171 errcopy = calloc(merrcopy, BUFSIZ);
176 if (noutcopy && logout_file != NULL)
179 if (nerrcopy && logerr_file != NULL)
180 PHYSFS_writeBytes( logerr_file, errcopy, strlen(errcopy) );
214static void log_cleanStream( PHYSFS_File **file,
const char *fname,
const char *filedouble )
221 PHYSFS_close( *file );
224 if (PHYSFS_stat( fname, &stat ) == 0)
227 if (stat.filesize == 0)
228 PHYSFS_delete( fname );
241 int len = strlen(str);
242 if (stream == stdout) {
243 while ((len + noutcopy) >= (
int)moutcopy) {
246 if (
outcopy == NULL)
goto copy_err;
249 strncpy( &
outcopy[noutcopy], str, len+1 );
252 else if (stream == stderr) {
253 while ((len + nerrcopy) >= (
int)merrcopy) {
255 errcopy = realloc( errcopy, merrcopy );
256 if (errcopy == NULL)
goto copy_err;
259 strncpy( &errcopy[nerrcopy], str, len+1 );
267 WARN(_(
"An error occurred while buffering %s!"),
268 stream == stdout ?
"stdout" :
"stderr");
void log_clean(void)
Deletes useless (empty) log files from the current session.
int logprintf(FILE *stream, int newline, const char *fmt,...)
Like fprintf, but automatically teed to log files (and line-terminated if newline is true).
void log_init(void)
Sets up the logging subsystem. (Calling this ensures logging output is preserved until we have a plac...
static void log_copy(int enable)
Sets up or terminates copying of standard streams into memory.
void log_redirect(void)
Sets up redirection of stdout and stderr to files. PhysicsFS must be initialized for this to work.
static void log_cleanStream(PHYSFS_File **file, const char *fname, const char *filedouble)
static void log_purge(void)
Deletes copied output without printing the contents.
static char * outfiledouble
static void log_append(FILE *stream, char *str)
Appends a message to a stream's in-memory buffer.
Header file with generic functions and naev-specifics.
int ndata_copyIfExists(const char *file1, const char *file2)
Copy a file, if it exists.