From 77ebaecf895b8b863e3e80382bd6ec0e18305dcd Mon Sep 17 00:00:00 2001 From: chatty Date: Tue, 27 Jul 1993 13:51:56 +0000 Subject: Incorporated changes from mbl@prl and mbl@europarc --- comm/error.cc | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 10 deletions(-) (limited to 'comm/error.cc') diff --git a/comm/error.cc b/comm/error.cc index fc02eb9..aed7c0b 100644 --- a/comm/error.cc +++ b/comm/error.cc @@ -17,7 +17,12 @@ #include #include #include +#ifdef sun +extern "C" int rename (const char*, const char*); +#endif #include +#include +#include "ccu/Time.h" /*?class UchERROR The set of global functions described here are designed to handle errors. @@ -60,8 +65,13 @@ char* ErrorTable [] = { "Subclass should implement virtual member", // ErrShouldImplement }; -static char ProgName [128], LogFile [128]; +static char ProgName [256], LogFile [256]; static bool LogOn =FALSE; +static int LogFd = -1; +static off_t LogSize = 0; +static off_t LogHalf = 0; + +#define LOG_HALF 25000 static errtype DefaultHandler (errtype how, const char* /*who*/, const char* /*what*/, const char* msg) @@ -82,7 +92,7 @@ HandleError (errtype how, const char* who, const char* what) char *msg = MakeErrorString (how, who, what); - if (how >= ErrLog && LogOn) { + if (how >= ErrLog) { LogMessage (msg); if (how == ErrLog) return TRUE; @@ -133,20 +143,77 @@ ProgramName (const char* name) /*? Set the log file name. All messages are appended to the logfile. -If \var{reset} is TRUE, the file is cleared. -NOTE : logging is not currently implemented. +If \var{reset} is TRUE, the file is renamed to \var{file\~}. +If this fails, the file is simply cleared. +If the \com{LOGDIR} environment variable is defined, and if \var{file} +does not start with \com{/} or \com{./}, the value of \com{LOGDIR} is +prepended to \var{file}, followed by a slash if necessary. +Otherwise, the directory \com{$HOME/.log} is used. ?*/ void LogfileName (const char* file, bool reset) { if (file) { - strncpy (LogFile, file, sizeof (LogFile) -1); + if (LogOn && LogFd >= 0) + close (LogFd); + if (*file == '/' || strncmp (file, "./", 2) == 0) { + LogFile [0] = '\0'; + } else { + // try $LOGDIR + char* dir = getenv ("LOGDIR"); + if (dir) { + strcpy (LogFile, dir); + } else { + // try $HOME/.log + char* home = getenv ("HOME"); + if (home) { + strcpy (LogFile, home); + strcat (LogFile, "/.log"); + if (access (LogFile, F_OK) != 0) { + // try to create the directory + if (mkdir (LogFile, 0755) != 0) { + Error (ErrWarn, "LogFileName", "logging to /tmp directory"); + strcpy (LogFile, "/tmp"); + } + } + } + } + if (LogFile [strlen (LogFile) - 1] != '/') + strcat (LogFile, "/"); + } + + strcat (LogFile, file); LogOn = TRUE; + int flags = O_RDWR | O_CREAT; if (reset) { - // to do: clear logfile + flags |= O_TRUNC; + // try to save previous version in LogFile~ + if (access (LogFile, F_OK) == 0) { + char old [256]; + strcpy (old, LogFile); + strcat (old, "~"); + rename (LogFile, old); + } + } + LogFd = open (LogFile, flags, 0644); + if (LogFd < 0) { + SysError (ErrWarn, "LogfileName"); + LogOn = FALSE; + } else { + LogHalf = 0; + if (reset) + LogSize = 0; + else { + LogSize = lseek (LogFd, 0L, 2 /*SEEK_END*/); + LogSize += write (LogFd, "\n", 1); + } + LogMessage ("-------- logging started --------\n"); } - } else + } else { + if (LogOn && LogFd >= 0) + close (LogFd); LogOn = FALSE; + } } /*?nodoc?*/ @@ -158,12 +225,43 @@ CleanUp (CleanUpProc) /*? Append a message to the logfile, if one has been specified. -NOTE : logging is not currently implemented. ?*/ void -LogMessage (const char*) +LogMessage (const char* msg) { - // to be done + if (! LogOn || LogFd < 0) + return; + + CcuTimeStamp now; + // format of time: Sun Sep 16 01:03:52 1973\n\0 + // 123456789012345678901234 + LogSize += write (LogFd, now.AsString (), 20); // strip year + LogSize += write (LogFd, msg, strlen (msg)); + + // limit the size of the log file + if (LogSize > LOG_HALF && LogHalf == 0) + LogHalf = LogSize; + + if (LogSize < 2 * LOG_HALF) + return; + + // copy bytes from LogHalf to LogSize to beginning of file + off_t src, dst; + int n; + char buf [4096]; + lseek (LogFd, 0L, 0 /*SEEK_SET*/); + write (LogFd, "...\n", 4); + for (src = LogHalf, dst = 4; src < LogSize; src += n, dst += n) { + lseek (LogFd, src, 0 /*SEEK_SET*/); + n = read (LogFd, buf, sizeof (buf)); + if (n <= 0) + break; + lseek (LogFd, dst, 0 /*SEEK_SET*/); + write (LogFd, buf, n); + } + lseek (LogFd, dst, 0 /*SEEK_SET*/); +////// ftruncate (LogFd, dst); /////// this seems not to be a POSIX call + LogHalf = LogSize = dst; } /*? -- cgit v1.1