diff --git a/os/log.c b/os/log.c
index f51976284092685c3adfc4eb117394159e6373be..54f6d2efa26a54f5046bfb6ea9869812b215a889 100644 (file)
--- a/os/log.c
+++ b/os/log.c
#include <stdlib.h> /* for malloc() */
#include <errno.h>
+#include <signal.h> /* for raise() */
+
#include "input.h"
#include "site.h"
#include "opaque.h"
#ifndef X_NOT_IMPLEMENTED_STRING
#define X_NOT_IMPLEMENTED_STRING "(NI)"
#endif
+#ifndef X_DEBUG_STRING
+#define X_DEBUG_STRING "(DB)"
+#endif
+#ifndef X_NONE_STRING
+#define X_NONE_STRING ""
+#endif
/*
* LogInit is called to start logging to a file. It is also called (with
* needed.
*/
if (saveBuffer && bufferSize > 0) {
- free(saveBuffer); /* Must be free(), not free() */
+ free(saveBuffer);
saveBuffer = NULL;
bufferSize = 0;
}
}
/* This function does the actual log message writes. */
-
-void
-LogVWrite(int verb, const char *f, va_list args)
+static void
+LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
{
- static char tmpBuffer[1024];
- int len = 0;
static Bool newline = TRUE;
- if (newline) {
- sprintf(tmpBuffer, "[%10.3f] ", GetTimeInMillis() / 1000.0);
- len = strlen(tmpBuffer);
- if (logFile)
- fwrite(tmpBuffer, len, 1, logFile);
- }
-
- /*
- * Since a va_list can only be processed once, write the string to a
- * buffer, and then write the buffer out to the appropriate output
- * stream(s).
- */
- if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
- vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
- len = strlen(tmpBuffer);
- }
- newline = (tmpBuffer[len-1] == '\n');
- if ((verb < 0 || logVerbosity >= verb) && len > 0)
- fwrite(tmpBuffer, len, 1, stderr);
- if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
+ if (verb < 0 || logVerbosity >= verb)
+ fwrite(buf, len, 1, stderr);
+ if (verb < 0 || logFileVerbosity >= verb) {
if (logFile) {
- fwrite(tmpBuffer, len, 1, logFile);
+ if (newline)
+ fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
+ newline = end_line;
+ fwrite(buf, len, 1, logFile);
if (logFlush) {
fflush(logFile);
#ifndef WIN32
FatalError("realloc() failed while saving log messages\n");
}
bufferUnused -= len;
- memcpy(saveBuffer + bufferPos, tmpBuffer, len);
+ memcpy(saveBuffer + bufferPos, buf, len);
bufferPos += len;
}
}
}
+void
+LogVWrite(int verb, const char *f, va_list args)
+{
+ return LogVMessageVerb(X_NONE, verb, f, args);
+}
+
void
LogWrite(int verb, const char *f, ...)
{
va_end(args);
}
+/* Returns the Message Type string to prepend to a logging message, or NULL
+ * if the message will be dropped due to insufficient verbosity. */
+static const char *
+LogMessageTypeVerbString(MessageType type, int verb)
+{
+ if (type == X_ERROR)
+ verb = 0;
+
+ if (logVerbosity < verb && logFileVerbosity < verb)
+ return NULL;
+
+ switch (type) {
+ case X_PROBED:
+ return X_PROBE_STRING;
+ case X_CONFIG:
+ return X_CONFIG_STRING;
+ case X_DEFAULT:
+ return X_DEFAULT_STRING;
+ case X_CMDLINE:
+ return X_CMDLINE_STRING;
+ case X_NOTICE:
+ return X_NOTICE_STRING;
+ case X_ERROR:
+ return X_ERROR_STRING;
+ case X_WARNING:
+ return X_WARNING_STRING;
+ case X_INFO:
+ return X_INFO_STRING;
+ case X_NOT_IMPLEMENTED:
+ return X_NOT_IMPLEMENTED_STRING;
+ case X_UNKNOWN:
+ return X_UNKNOWN_STRING;
+ case X_NONE:
+ return X_NONE_STRING;
+ case X_DEBUG:
+ return X_DEBUG_STRING;
+ default:
+ return X_UNKNOWN_STRING;
+ }
+}
+
void
LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
{
- const char *s = X_UNKNOWN_STRING;
- char tmpBuf[1024];
-
- /* Ignore verbosity for X_ERROR */
- if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
- switch (type) {
- case X_PROBED:
- s = X_PROBE_STRING;
- break;
- case X_CONFIG:
- s = X_CONFIG_STRING;
- break;
- case X_DEFAULT:
- s = X_DEFAULT_STRING;
- break;
- case X_CMDLINE:
- s = X_CMDLINE_STRING;
- break;
- case X_NOTICE:
- s = X_NOTICE_STRING;
- break;
- case X_ERROR:
- s = X_ERROR_STRING;
- if (verb > 0)
- verb = 0;
- break;
- case X_WARNING:
- s = X_WARNING_STRING;
- break;
- case X_INFO:
- s = X_INFO_STRING;
- break;
- case X_NOT_IMPLEMENTED:
- s = X_NOT_IMPLEMENTED_STRING;
- break;
- case X_UNKNOWN:
- s = X_UNKNOWN_STRING;
- break;
- case X_NONE:
- s = NULL;
- break;
- }
+ const char *type_str;
+ char buf[1024];
+ const size_t size = sizeof(buf);
+ Bool newline;
+ size_t len = 0;
- /* if s is not NULL we need a space before format */
- snprintf(tmpBuf, sizeof(tmpBuf), "%s%s%s", s ? s : "",
- s ? " " : "",
- format);
- LogVWrite(verb, tmpBuf, args);
- }
+ type_str = LogMessageTypeVerbString(type, verb);
+ if (!type_str)
+ return;
+
+ /* if type_str is not "", prepend it and ' ', to message */
+ if (type_str[0] != '\0')
+ len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
+
+ if (size - len > 1)
+ len += Xvscnprintf(&buf[len], size - len, format, args);
+
+ /* Force '\n' at end of truncated line */
+ if (size - len == 1)
+ buf[len - 1] = '\n';
+
+ newline = (buf[len - 1] == '\n');
+ LogSWrite(verb, buf, len, newline);
}
/* Log message with verbosity level specified. */
va_end(ap);
}
+void
+LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
+ va_list msg_args, const char *hdr_format, va_list hdr_args)
+{
+ const char *type_str;
+ char buf[1024];
+ const size_t size = sizeof(buf);
+ Bool newline;
+ size_t len = 0;
+
+ type_str = LogMessageTypeVerbString(type, verb);
+ if (!type_str)
+ return;
+
+ /* if type_str is not "", prepend it and ' ', to message */
+ if (type_str[0] != '\0')
+ len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
+
+ if (hdr_format && size - len > 1)
+ len += Xvscnprintf(&buf[len], size - len, hdr_format, hdr_args);
+
+ if (msg_format && size - len > 1)
+ len += Xvscnprintf(&buf[len], size - len, msg_format, msg_args);
+
+ /* Force '\n' at end of truncated line */
+ if (size - len == 1)
+ buf[len - 1] = '\n';
+
+ newline = (buf[len - 1] == '\n');
+ LogSWrite(verb, buf, len, newline);
+}
+
+void
+LogHdrMessageVerb(MessageType type, int verb, const char *msg_format,
+ va_list msg_args, const char *hdr_format, ...)
+{
+ va_list hdr_args;
+
+ va_start(hdr_args, hdr_format);
+ LogVHdrMessageVerb(type, verb, msg_format, msg_args, hdr_format, hdr_args);
+ va_end(hdr_args);
+}
+
void
AbortServer(void) _X_NORETURN;
+void
+SigAbortServer(int signo) _X_NORETURN;
void
-AbortServer(void)
+SigAbortServer(int signo)
{
#ifdef XF86BIGFONT
XF86BigfontCleanup();
CloseWellKnownConnections();
OsCleanup(TRUE);
CloseDownDevices();
- AbortDDX(EXIT_ERR_ABORT);
+ SigAbortDDX(signo, EXIT_ERR_ABORT);
fflush(stderr);
- if (CoreDump)
- OsAbort();
- exit (1);
+ if (CoreDump) {
+ if (signo != 0)
+ raise(signo);
+ else
+ OsAbort();
+ } else {
+ exit (1);
+ }
+}
+
+void
+AbortServer()
+{
+ SigAbortServer(0);
}
#define AUDIT_PREFIX "AUDIT: %s: %ld: "
free(prefix);
}
+void
+FatalSignal(int signo)
+{
+ static Bool beenhere = FALSE;
+
+ if (beenhere)
+ ErrorF("\nFatalSignal re-entered, aborting\n");
+ else
+ ErrorF("\nCaught signal %d (%s). Server aborting\n",
+ signo, strsignal(signo));
+
+ if (!beenhere)
+ OsVendorFatalError();
+ if (!beenhere) {
+ beenhere = TRUE;
+ SigAbortServer(signo);
+ } else
+ abort();
+ /*NOTREACHED*/
+}
+
void
FatalError(const char *f, ...)
{