瀏覽代碼

bugfix: when we run out of disk space, or other log writing error,
don't crash. just stop logging to that log and continue.

nick, can you find the bug i've cleverly hidden in this commit?


svn:r2365

Roger Dingledine 21 年之前
父節點
當前提交
f753f6f0e2
共有 1 個文件被更改,包括 36 次插入15 次删除
  1. 36 15
      src/common/log.c

+ 36 - 15
src/common/log.c

@@ -139,22 +139,32 @@ logv(int severity, const char *funcname, const char *format, va_list ap)
   logfile_t *lf;
 
   assert(format);
-  for (lf = logfiles; lf; lf = lf->next) {
-    if (severity < lf->loglevel || severity > lf->max_loglevel)
+  lf = logfiles;
+  while(lf) {
+    if (severity < lf->loglevel || severity > lf->max_loglevel) {
+      lf = lf->next;
       continue;
-    if (!lf->file)
+    }
+    if (!lf->file) {
+      lf = lf->next;
       continue;
+    }
 
     if (!formatted) {
-      format_msg(buf, 10024, severity, funcname, format, ap);
+      format_msg(buf, sizeof(buf), severity, funcname, format, ap);
       formatted = 1;
     }
-    if(fputs(buf, lf->file) == EOF) { /* error */
-      assert(0); /* XXX */
-    }
-    if(fflush(lf->file) == EOF) { /* error */
-      /* don't log the error! */
-      assert(0); /* XXX fail for now. what's better to do? */
+    if(fputs(buf, lf->file) == EOF ||
+       fflush(lf->file) == EOF) { /* error */
+      /* don't log the error! Blow away this log entry and continue. */
+      logfile_t *victim = lf;
+      lf = victim->next;
+      if(victim == logfiles)
+        logfiles = lf;
+      tor_free(victim->filename);
+      tor_free(victim);
+    } else {
+      lf = lf->next;
     }
   }
 }
@@ -194,13 +204,24 @@ void close_logs()
 /** Close and re-open all log files; used to rotate logs on SIGHUP. */
 void reset_logs()
 {
-  logfile_t *lf;
-  for (lf = logfiles; lf; lf = lf->next) {
+  logfile_t *lf = logfiles;
+  while(lf) {
     if (lf->needs_close) {
-      fclose(lf->file);
-      lf->file = fopen(lf->filename, "a");
-      log_tor_version(lf, 1);
+      if(fclose(lf->file)==EOF ||
+        !(lf->file = fopen(lf->filename, "a"))) {
+        /* error. don't log it. delete the log entry and continue. */
+        logfile_t *victim = lf;
+        lf = victim->next;
+        if(victim == logfiles)
+          logfiles = lf;
+        tor_free(victim->filename);
+        tor_free(victim);
+        continue;
+      } else {
+        log_tor_version(lf, 1);
+      }
     }
+    lf = lf->next;
   }
 }