[PATCH] os: automatically switch to sigsafe logging when needed

Peter Hutterer peter.hutterer at who-t.net
Wed May 14 20:14:58 PDT 2014


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 at who-t.net>
---
 os/log.c | 65 ++++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/os/log.c b/os/log.c
index a0f2a81..a368569 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)
-- 
1.9.0



More information about the xorg-devel mailing list