hopefully fix the seg fault on darwin
authorTony Cook <tony@develop-help.com>
Mon, 22 Oct 2012 11:18:57 +0000 (22:18 +1100)
committerTony Cook <tony@develop-help.com>
Sat, 24 Nov 2012 04:05:54 +0000 (15:05 +1100)
also fixes a leak where the old fh wasn't closed when init_log was called

context.c
imageri.h
log.c

index cab65a9..4645ebf 100644 (file)
--- a/context.c
+++ b/context.c
@@ -116,7 +116,7 @@ im_context_refdec(im_context_t ctx, const char *where) {
       myfree(ctx->error_stack[i].msg);
   }
 #ifdef IMAGER_LOG
-  if (ctx->lg_file)
+  if (ctx->lg_file && ctx->own_log)
     fclose(ctx->lg_file);
 #endif
 
@@ -163,13 +163,18 @@ im_context_clone(im_context_t ctx, const char *where) {
 #ifdef IMAGER_LOG
   nctx->log_level = ctx->log_level;
   if (ctx->lg_file) {
-    /* disable buffering, this isn't perfect */
-    setvbuf(ctx->lg_file, NULL, _IONBF, 0);
-
-    /* clone that and disable buffering some more */
-    nctx->lg_file = fdopen(fileno(ctx->lg_file), "a");
-    if (nctx->lg_file)
-      setvbuf(nctx->lg_file, NULL, _IONBF, 0);
+    if (ctx->own_log) {
+      int newfd = dup(fileno(ctx->lg_file));
+      nctx->own_log = 1;
+      nctx->lg_file = fdopen(newfd, "w");
+      if (nctx->lg_file)
+       setvbuf(nctx->lg_file, NULL, _IONBF, BUFSIZ);
+    }
+    else {
+      /* stderr */
+      nctx->lg_file = ctx->lg_file;
+      nctx->own_log = 0;
+    }
   }
   else {
     nctx->lg_file = NULL;
index 6ef28a7..2848bcf 100644 (file)
--- a/imageri.h
+++ b/imageri.h
@@ -118,8 +118,14 @@ typedef struct im_context_tag {
   size_t error_alloc[IM_ERROR_COUNT];
   i_errmsg error_stack[IM_ERROR_COUNT];
 #ifdef IMAGER_LOG
-  int log_level;
+  /* the log file and level for this context */
   FILE *lg_file;
+  int log_level;
+
+  /* whether we own the lg_file, false for stderr and for cloned contexts */
+  int own_log;
+
+  /* values supplied by lhead */
   const char *filename;
   int line;
 #endif
diff --git a/log.c b/log.c
index 34b7770..34e4a73 100644 (file)
--- a/log.c
+++ b/log.c
@@ -30,21 +30,30 @@ im_vloog(pIMCTX, int level, const char *fmt, va_list ap);
 int
 im_init_log(pIMCTX, const char* name,int level) {
   i_clear_error();
+
+  if (aIMCTX->lg_file) {
+    if (aIMCTX->own_log)
+      fclose(aIMCTX->lg_file);
+    aIMCTX->lg_file = NULL;
+  }
+  
   aIMCTX->log_level = level;
   if (level < 0) {
     aIMCTX->lg_file = NULL;
   } else {
     if (name == NULL) {
       aIMCTX->lg_file = stderr;
+      aIMCTX->own_log = 0;
     } else {
       if (NULL == (aIMCTX->lg_file = fopen(name, "w+")) ) { 
        im_push_errorf(aIMCTX, errno, "Cannot open file '%s': (%d)", name, errno);
        return 0;
       }
+      aIMCTX->own_log = 1;
+      setvbuf(aIMCTX->lg_file, NULL, _IONBF, BUFSIZ);
     }
   }
   if (aIMCTX->lg_file) {
-    setvbuf(aIMCTX->lg_file, NULL, _IONBF, BUFSIZ);
     im_log((aIMCTX, 0,"Imager - log started (level = %d)\n", level));
   }