Bug 244478: allow a logging line to be longer than LINE_BUF_SIZE (512)
authorwtc%google.com
Mon, 03 Sep 2007 15:41:09 +0000
changeset 3865 e8b7660b6c37d690cbd67b1737b0ca9ce70b3627
parent 3863 cfc0c71869c53e66333b04916d8989efbef8201f
child 3866 48ddfcb81318137e05678bd8b981b8782b36a592
push idunknown
push userunknown
push dateunknown
bugs244478
Bug 244478: allow a logging line to be longer than LINE_BUF_SIZE (512) characters. The patch is contributed by Dan Witte <dwitte@stanford.edu>. r=wtc.
pr/src/io/prlog.c
--- a/pr/src/io/prlog.c
+++ b/pr/src/io/prlog.c
@@ -248,17 +248,17 @@ void _PR_InitLog(void)
                     lm = lm->next;
                 }
             }
             /*found:*/
             count = sscanf(&ev[pos], " , %n", &delta);
             pos += delta;
             if (count == EOF) break;
         }
-        PR_SetLogBuffering(isSync ? bufSize : 0);
+        PR_SetLogBuffering(isSync ? 0 : bufSize);
 
 #ifdef XP_UNIX
         if ((getuid() != geteuid()) || (getgid() != getegid())) {
             return;
         }
 #endif /* XP_UNIX */
 
         ev = PR_GetEnv("NSPR_LOG_FILE");
@@ -437,66 +437,91 @@ PR_IMPLEMENT(void) PR_SetLogBuffering(PR
         logEndp = logp + buffer_size;
     }
 }
 
 PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...)
 {
     va_list ap;
     char line[LINE_BUF_SIZE];
-    PRUint32 nb;
+    char *line_long = NULL;
+    PRUint32 nb_tid, nb;
     PRThread *me;
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
     if (!logFile) {
         return;
     }
 
-    va_start(ap, fmt);
     me = PR_GetCurrentThread();
-    nb = PR_snprintf(line, sizeof(line)-1, "%ld[%p]: ",
+    nb_tid = PR_snprintf(line, sizeof(line)-1, "%ld[%p]: ",
 #if defined(_PR_DCETHREADS)
              /* The problem is that for _PR_DCETHREADS, pthread_t is not a 
               * pointer, but a structure; so you can't easily print it...
               */
-                     me ? &(me->id): 0L, me);
+                         me ? &(me->id): 0L, me);
 #elif defined(_PR_BTHREADS)
-		     me, me);
+                         me, me);
 #else
-                     me ? me->id : 0L, me);
+                         me ? me->id : 0L, me);
 #endif
 
-    nb += PR_vsnprintf(line+nb, sizeof(line)-nb-1, fmt, ap);
-    if (nb && (line[nb-1] != '\n')) {
-#ifndef XP_MAC
-        line[nb++] = '\n';
-#else
-        line[nb++] = '\015';
-#endif 
-        line[nb] = '\0';
-    } else {
-#ifdef XP_MAC
-        line[nb-1] = '\015';
-#endif
-    }
+    va_start(ap, fmt);
+    nb = nb_tid + PR_vsnprintf(line+nb_tid, sizeof(line)-nb_tid-1, fmt, ap);
     va_end(ap);
 
-    _PR_LOCK_LOG();
-    if (logBuf == 0) {
-        _PUT_LOG(logFile, line, nb);
-    } else {
-        if (logp + nb > logEndp) {
+    /*
+     * Check if we might have run out of buffer space (in case we have a
+     * long line), and malloc a buffer just this once.
+     */
+    if (nb == sizeof(line)-2) {
+        va_start(ap, fmt);
+        line_long = PR_vsmprintf(fmt, ap);
+        va_end(ap);
+        /* If this failed, we'll fall back to writing the truncated line. */
+    }
+
+    if (line_long) {
+        nb = strlen(line_long);
+        _PR_LOCK_LOG();
+        if (logBuf != 0) {
             _PUT_LOG(logFile, logBuf, logp - logBuf);
             logp = logBuf;
         }
-        memcpy(logp, line, nb);
-        logp += nb;
+        /* Write out the thread id and the malloc'ed buffer. */
+        _PUT_LOG(logFile, line, nb_tid);
+        _PUT_LOG(logFile, line_long, nb);
+        /* Ensure there is a trailing newline. */
+        if (!nb || (line_long[nb-1] != '\n')) {
+            _PUT_LOG(logFile, "\n", 1);
+        }
+        _PR_UNLOCK_LOG();
+        PR_smprintf_free(line_long);
+    } else {
+        /* Ensure there is a trailing newline. */
+        if (nb && (line[nb-1] != '\n')) {
+            line[nb++] = '\n';
+            line[nb] = '\0';
+        }
+        _PR_LOCK_LOG();
+        if (logBuf == 0) {
+            _PUT_LOG(logFile, line, nb);
+        } else {
+            /* If nb can't fit into logBuf, write out logBuf first. */
+            if (logp + nb > logEndp) {
+                _PUT_LOG(logFile, logBuf, logp - logBuf);
+                logp = logBuf;
+            }
+            /* nb is guaranteed to fit into logBuf. */
+            memcpy(logp, line, nb);
+            logp += nb;
+        }
+        _PR_UNLOCK_LOG();
     }
-    _PR_UNLOCK_LOG();
     PR_LogFlush();
 }
 
 PR_IMPLEMENT(void) PR_LogFlush(void)
 {
     if (logBuf && logFile) {
         _PR_LOCK_LOG();
             if (logp > logBuf) {