]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/log-file.c
ucw. docs: document single-line doc. comments
[libucw.git] / ucw / log-file.c
index 65e9eb85df41541ccba86c0d0bf3c5d58d80f8bd..cd0d037c478e0e09ffe7a58c90ae9b35055d6c0c 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "ucw/lib.h"
 #include "ucw/log.h"
 
 #include "ucw/lib.h"
 #include "ucw/log.h"
+#include "ucw/log-internal.h"
 #include "ucw/lfs.h"
 #include "ucw/threads.h"
 #include "ucw/simple-lists.h"
 #include "ucw/lfs.h"
 #include "ucw/threads.h"
 #include "ucw/simple-lists.h"
@@ -30,6 +31,7 @@ struct file_stream {
 enum log_file_flag {
   FF_FORMAT_NAME = 1,          // Name contains strftime escapes
   FF_CLOSE_FD = 2,             // Close the fd with the stream
 enum log_file_flag {
   FF_FORMAT_NAME = 1,          // Name contains strftime escapes
   FF_CLOSE_FD = 2,             // Close the fd with the stream
+  FF_FD2_FOLLOWS = 4,          // Maintain stderr as a clone of this stream
 };
 
 #define MAX_EXPAND 64          // Maximum size of expansion of strftime escapes
 };
 
 #define MAX_EXPAND 64          // Maximum size of expansion of strftime escapes
@@ -42,17 +44,15 @@ do_log_reopen(struct file_stream *fs, const char *name)
   int fd = ucw_open(name, O_WRONLY | O_CREAT | O_APPEND, 0666);
   if (fd < 0)
     die("Unable to open log file %s: %m", name);
   int fd = ucw_open(name, O_WRONLY | O_CREAT | O_APPEND, 0666);
   if (fd < 0)
     die("Unable to open log file %s: %m", name);
-  if (fs->fd < 0)
-    fs->fd = fd;
-  else
-    {
-      dup2(fd, fs->fd);
-      close(fd);
-    }
+  if (fs->fd >= 0)
+    close(fs->fd);
+  fs->fd = fd;
+  if (fs->flags & FF_FD2_FOLLOWS)
+    dup2(fd, 2);
   if (fs->ls.name)
     {
       xfree(fs->ls.name);
   if (fs->ls.name)
     {
       xfree(fs->ls.name);
-      fs->ls.name = NULL;      // We have to keep this consistent, die() below can invoke logging
+      fs->ls.name = NULL;      // We have to keep the stream consistent -- die() below can invoke logging
     }
   fs->ls.name = xstrdup(name);
 }
     }
   fs->ls.name = xstrdup(name);
 }
@@ -93,21 +93,6 @@ do_log_switch(struct file_stream *fs, struct tm *tm)
   return switched;
 }
 
   return switched;
 }
 
-/* Emulate the old single-file interface: close the existing log file and open a new one. */
-void
-log_file(const char *name)
-{
-  if (!name)
-    return;
-
-  struct log_stream *ls = log_new_file(name);
-  struct log_stream *def = log_stream_by_flags(0);
-  log_rm_substream(def, NULL);
-  log_add_substream(def, ls);
-  dup2(((struct file_stream *)ls)->fd, 2);                     // Let fd2 be an alias for the log file
-}
-
-/* destructor for standard files */
 static void
 file_close(struct log_stream *ls)
 {
 static void
 file_close(struct log_stream *ls)
 {
@@ -118,7 +103,6 @@ file_close(struct log_stream *ls)
   xfree(fs->orig_name);
 }
 
   xfree(fs->orig_name);
 }
 
-/* handler for standard files */
 static int
 file_handler(struct log_stream *ls, struct log_msg *m)
 {
 static int
 file_handler(struct log_stream *ls, struct log_msg *m)
 {
@@ -131,8 +115,6 @@ file_handler(struct log_stream *ls, struct log_msg *m)
   return 0;
 }
 
   return 0;
 }
 
-/* assign log to a file descriptor */
-/* initialize with the default formatting, does NOT close the descriptor */
 struct log_stream *
 log_new_fd(int fd)
 {
 struct log_stream *
 log_new_fd(int fd)
 {
@@ -147,10 +129,8 @@ log_new_fd(int fd)
   return ls;
 }
 
   return ls;
 }
 
-/* open() a file (append mode) */
-/* initialize with the default formatting */
-struct log_stream *
-log_new_file(const char *path)
+static struct log_stream *
+do_log_new_file(const char *path, uns more_flags)
 {
   struct log_stream *ls = log_new_stream(sizeof(struct file_stream));
   struct file_stream *fs = (struct file_stream *) ls;
 {
   struct log_stream *ls = log_new_stream(sizeof(struct file_stream));
   struct file_stream *fs = (struct file_stream *) ls;
@@ -158,7 +138,7 @@ log_new_file(const char *path)
   fs->orig_name = xstrdup(path);
   if (strchr(path, '%'))
     fs->flags = FF_FORMAT_NAME;
   fs->orig_name = xstrdup(path);
   if (strchr(path, '%'))
     fs->flags = FF_FORMAT_NAME;
-  fs->flags |= FF_CLOSE_FD;
+  fs->flags |= FF_CLOSE_FD | more_flags;
   ls->msgfmt = LSFMT_DEFAULT;
   ls->handler = file_handler;
   ls->close = file_close;
   ls->msgfmt = LSFMT_DEFAULT;
   ls->handler = file_handler;
   ls->close = file_close;
@@ -170,6 +150,12 @@ log_new_file(const char *path)
   return ls;
 }
 
   return ls;
 }
 
+struct log_stream *
+log_new_file(const char *path)
+{
+  return do_log_new_file(path, 0);
+}
+
 int
 log_switch(void)
 {
 int
 log_switch(void)
 {
@@ -197,6 +183,18 @@ log_switch_enable(void)
   log_switch_nest--;
 }
 
   log_switch_nest--;
 }
 
+void
+log_file(const char *name)
+{
+  if (!name)
+    return;
+
+  struct log_stream *ls = do_log_new_file(name, FF_FD2_FOLLOWS);
+  struct log_stream *def = log_stream_by_flags(0);
+  log_rm_substream(def, NULL);
+  log_add_substream(def, ls);
+}
+
 #ifdef TEST
 
 int main(int argc, char **argv)
 #ifdef TEST
 
 int main(int argc, char **argv)