summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2014-05-08 09:39:36 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2014-05-23 11:08:13 +1000
commitd3a3ee7a0e5cbd3fcaba77d2d5664e1524eda11c (patch)
tree2de87d4874295f9eb954d9dbf9a204b16fdf2013
parentd5587cf3acb7ad6f81e1c095f1b88f8fb25ee953 (diff)
os: automatically switch to sigsafe logging when needed
If we're smart enough to warn, we should be smart enough to just pass it through to the right function. Worst case we lose some formatting specifiers which pnprintf will complain about anyway. And in most cases it won't matter. This requires renaming pnprintf to vpnprintf and changing the size_t to int to be compatible with Xvscnprintf. pnprintf is internal only, the others are exported API so we can't change them as easily. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Keith Packard <keithp@keithp.com>
-rw-r--r--os/log.c65
1 files changed, 33 insertions, 32 deletions
diff --git a/os/log.c b/os/log.c
index a0f2a81f3..a368569d0 100644
--- a/os/log.c
+++ b/os/log.c
@@ -342,7 +342,7 @@ out:
* which directives you use.
*/
static int
-pnprintf(char *string, size_t size, const char *f, va_list args)
+vpnprintf(char *string, int size_in, const char *f, va_list args)
{
int f_idx = 0;
int s_idx = 0;
@@ -353,6 +353,7 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
int i;
uint64_t ui;
int64_t si;
+ size_t size = size_in;
for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
int length_modifier = 0;
@@ -484,6 +485,19 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
return s_idx;
}
+static int
+pnprintf(char *string, int size, const char *f, ...)
+{
+ int rc;
+ va_list args;
+
+ va_start(args, f);
+ rc = vpnprintf(string, size, f, args);
+ va_end(args);
+
+ return rc;
+}
+
/* 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. */
@@ -597,7 +611,6 @@ LogMessageTypeVerbString(MessageType type, int verb)
void
LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
{
- static unsigned int warned;
const char *type_str;
char buf[1024];
const size_t size = sizeof(buf);
@@ -605,17 +618,8 @@ LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
size_t len = 0;
if (inSignalContext) {
- if (warned < 3) {
- BUG_WARN_MSG(inSignalContext,
- "Warning: attempting to log data in a signal unsafe "
- "manner while in signal context.\nPlease update to check "
- "inSignalContext and/or use LogMessageVerbSigSafe() or "
- "ErrorFSigSafe().\nThe offending log format message is:\n"
- "%s\n", format);
- warned++;
- if (warned == 3)
- LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned);
- }
+ LogVMessageVerbSigSafe(type, verb, format, args);
+ return;
}
type_str = LogMessageTypeVerbString(type, verb);
@@ -687,7 +691,7 @@ LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list a
LogSWrite(verb, " ", 1, FALSE);
}
- len = pnprintf(buf, sizeof(buf), format, args);
+ len = vpnprintf(buf, sizeof(buf), format, args);
/* Force '\n' at end of truncated line */
if (sizeof(buf) - len == 1)
@@ -701,40 +705,37 @@ void
LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
va_list msg_args, const char *hdr_format, va_list hdr_args)
{
- static unsigned int warned;
const char *type_str;
char buf[1024];
const size_t size = sizeof(buf);
Bool newline;
size_t len = 0;
-
- if (inSignalContext) {
- if (warned < 3) {
- BUG_WARN_MSG(inSignalContext,
- "Warning: attempting to log data in a signal unsafe "
- "manner while in signal context.\nPlease update to check "
- "inSignalContext and/or use LogMessageVerbSigSafe().\nThe "
- "offending header and log message formats are:\n%s %s\n",
- hdr_format, msg_format);
- warned++;
- if (warned == 3)
- LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned);
- }
- }
+ int (*vprintf_func)(char *, int, const char* _X_RESTRICT_KYWD f, va_list args)
+ _X_ATTRIBUTE_PRINTF(3, 0);
+ int (*printf_func)(char *, int, const char* _X_RESTRICT_KYWD f, ...)
+ _X_ATTRIBUTE_PRINTF(3, 4);
type_str = LogMessageTypeVerbString(type, verb);
if (!type_str)
return;
+ if (inSignalContext) {
+ vprintf_func = vpnprintf;
+ printf_func = pnprintf;
+ } else {
+ vprintf_func = Xvscnprintf;
+ printf_func = Xscnprintf;
+ }
+
/* if type_str is not "", prepend it and ' ', to message */
if (type_str[0] != '\0')
- len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
+ len += printf_func(&buf[len], size - len, "%s ", type_str);
if (hdr_format && size - len > 1)
- len += Xvscnprintf(&buf[len], size - len, hdr_format, hdr_args);
+ len += vprintf_func(&buf[len], size - len, hdr_format, hdr_args);
if (msg_format && size - len > 1)
- len += Xvscnprintf(&buf[len], size - len, msg_format, msg_args);
+ len += vprintf_func(&buf[len], size - len, msg_format, msg_args);
/* Force '\n' at end of truncated line */
if (size - len == 1)