Commit 164b38c7 authored by Chase Douglas's avatar Chase Douglas Committed by Keith Packard
Browse files

Add LogMessageVerbSigSafe() for logging messages while in signal context



[whot: edited to use varargs, squashed commit below]
Signed-off-by: default avatarChase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>

os: fix vararg length calculation

Make %u and %x sizeof(unsigned int), %p sizeof(void*). This is printf
behaviour and we can't guarantee that void* is uint64_t anyway.
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: default avatarChase Douglas <chase.douglas@canonical.com>
parent 704b847a
......@@ -49,6 +49,7 @@ SOFTWARE.
#include "misc.h"
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#define SCREEN_SAVER_ON 0
......@@ -604,6 +605,12 @@ _X_ATTRIBUTE_PRINTF(3, 4);
extern _X_EXPORT void
LogMessage(MessageType type, const char *format, ...)
_X_ATTRIBUTE_PRINTF(2, 3);
extern _X_EXPORT void
LogMessageVerbSigSafe(MessageType type, int verb, const char *format, ...)
_X_ATTRIBUTE_PRINTF(3, 4);
extern _X_EXPORT void
LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list args)
_X_ATTRIBUTE_PRINTF(3, 0);
extern _X_EXPORT void
LogVHdrMessageVerb(MessageType type, int verb,
......
......@@ -172,6 +172,14 @@ asm(".desc ___crashreporter_info__, 0x10");
#define X_NONE_STRING ""
#endif
static size_t
strlen_sigsafe(const char *s)
{
size_t len;
for (len = 0; s[len]; len++);
return len;
}
/*
* LogInit is called to start logging to a file. It is also called (with
* NULL arguments) when logging to a file is not wanted. It must always be
......@@ -271,16 +279,97 @@ LogSetParameter(LogParameter param, int value)
}
}
/* This function does the actual log message writes. */
static int
pnprintf(char *string, size_t size, const char *f, va_list args)
{
int f_idx = 0;
int s_idx = 0;
int f_len = strlen_sigsafe(f);
char *string_arg;
char number[21];
int p_len;
int i;
uint64_t ui;
for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
if (f[f_idx] != '%') {
string[s_idx++] = f[f_idx];
continue;
}
switch (f[++f_idx]) {
case 's':
string_arg = va_arg(args, char*);
p_len = strlen_sigsafe(string_arg);
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = string_arg[i];
break;
case 'u':
ui = va_arg(args, unsigned);
FormatUInt64(ui, number);
p_len = strlen_sigsafe(number);
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i];
break;
case 'p':
string[s_idx++] = '0';
if (s_idx < size - 1)
string[s_idx++] = 'x';
ui = (uintptr_t)va_arg(args, void*);
FormatUInt64Hex(ui, number);
p_len = strlen_sigsafe(number);
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i];
break;
case 'x':
ui = va_arg(args, unsigned);
FormatUInt64Hex(ui, number);
p_len = strlen_sigsafe(number);
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i];
break;
default:
va_arg(args, char*);
string[s_idx++] = '%';
if (s_idx < size - 1)
string[s_idx++] = f[f_idx];
break;
}
}
string[s_idx] = '\0';
return s_idx;
}
/* This function does the actual log message writes. It must be signal safe.
* When attempting to call non-signal-safe functions, guard them with a check
* of the inSignalContext global variable. */
static void
LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
{
static Bool newline = TRUE;
if (verb < 0 || logVerbosity >= verb)
fwrite(buf, len, 1, stderr);
write(2, buf, len);
if (verb < 0 || logFileVerbosity >= verb) {
if (logFile) {
if (inSignalContext && logFileFd >= 0) {
write(logFileFd, buf, len);
#ifdef WIN32
if (logFlush && logSync)
fsync(logFileFd);
#endif
}
else if (!inSignalContext && logFile) {
if (newline)
fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
newline = end_line;
......@@ -293,7 +382,7 @@ LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
#endif
}
}
else if (needBuffer) {
else if (!inSignalContext && needBuffer) {
if (len > bufferUnused) {
bufferSize += 1024;
bufferUnused += 1024;
......@@ -415,6 +504,44 @@ LogMessage(MessageType type, const char *format, ...)
va_end(ap);
}
/* Log a message using only signal safe functions. */
void
LogMessageVerbSigSafe(MessageType type, int verb, const char *format, ...)
{
va_list ap;
va_start(ap, format);
LogVMessageVerbSigSafe(type, verb, format, ap);
va_end(ap);
}
void
LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list args)
{
const char *type_str;
char buf[1024];
int len;
Bool newline;
type_str = LogMessageTypeVerbString(type, verb);
if (!type_str)
return;
/* if type_str is not "", prepend it and ' ', to message */
if (type_str[0] != '\0') {
LogSWrite(verb, type_str, strlen_sigsafe(type_str), FALSE);
LogSWrite(verb, " ", 1, FALSE);
}
len = pnprintf(buf, sizeof(buf), format, args);
/* Force '\n' at end of truncated line */
if (sizeof(buf) - len == 1)
buf[len - 1] = '\n';
newline = (buf[len - 1] == '\n');
LogSWrite(verb, buf, len, newline);
}
void
LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
va_list msg_args, const char *hdr_format, va_list hdr_args)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment