[mythtv] [patch] log rotation

Kyle Rose krose+mythtv at krose.org
Thu Feb 10 19:12:12 UTC 2005


Here's a last-minute patch I'd like to sneak in.  It rotates the log
(i.e., reopens the logfile and dup2's it onto fd 1 and 2) when SIGHUP
is sent to mythbackend.  Note that there are restrictions on what you
can do within a signal handler (specifically with regard to pthreads),
which is why there are no QString operations or printf's within the
handler below to indicate an error to the user, except when called
from the main program.

Let me know if there are any problems.

Cheers,
Kyle

Index: programs/mythbackend/main.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythbackend/main.cpp,v
retrieving revision 1.81
diff -u -r1.81 main.cpp
--- programs/mythbackend/main.cpp       28 Jan 2005 04:06:31 -0000      1.81
+++ programs/mythbackend/main.cpp       10 Feb 2005 19:11:37 -0000
@@ -33,6 +33,7 @@
 QString pidfile;
 QString lockfile_location;
 HouseKeeper *housekeeping = NULL;
+char *logfile_c = NULL;
 
 bool setupTVs(bool ismaster)
 {
@@ -158,8 +159,39 @@
         unlink(pidfile.ascii());
 
     unlink(lockfile_location.ascii());
+
+    signal(SIGHUP, SIG_DFL);
+
+    if (logfile_c != NULL)
+        free(logfile_c);
+}
+
+int log_rotate(int report_error)
+{
+    int new_logfd = open(logfile_c, O_WRONLY|O_CREAT|O_APPEND|O_SYNC, 0664);
+    if (new_logfd < 0) {
+        /* If we can't open the new logfile, send data to /dev/null */
+        if (report_error) {
+            cerr << "cannot open logfile " << logfile_c << endl;
+            return -1;
+        }
+        new_logfd = open("/dev/null", O_WRONLY);
+        if (new_logfd < 0) {
+            /* There's not much we can do, so punt. */
+            return -1;
+        }
+    }
+    while (dup2(new_logfd, 1) < 0 && errno == EINTR) ;
+    while (dup2(new_logfd, 2) < 0 && errno == EINTR) ;
+    while (close(new_logfd) < 0 && errno == EINTR) ;
+    return 0;
 }
     
+void log_rotate_handler(int)
+{
+    log_rotate(0);
+}
+
 int main(int argc, char **argv)
 {
     for(int i = 3; i < sysconf(_SC_OPEN_MAX) - 1; ++i)
@@ -364,18 +396,11 @@
         }
     }
 
-    int logfd = -1;
-
-    if (logfile != "")
-    {
-        logfd = open(logfile.ascii(), O_WRONLY|O_CREAT|O_APPEND|O_SYNC, 0664);
-         
-        if (logfd < 0)
-        {
-            perror(logfile.ascii());
-            cerr << "Error opening logfile\n";
-            return -1;
-        }
+    if (logfile != "" && (logfile_c = strdup(logfile.ascii())) != NULL) {
+        if (log_rotate(1) < 0)
+            cerr << "cannot open logfile; using stdout/stderr" << endl;
+        else
+            signal(SIGHUP, &log_rotate_handler);
     }
     
     ofstream pidfs;
@@ -407,17 +432,6 @@
         pidfs.close();
     }
 
-    if (logfd != -1)
-    {
-        // Send stdout and stderr to the logfile
-        dup2(logfd, 1);
-        dup2(logfd, 2);
-
-        // Close the unduplicated logfd
-        if (logfd != 1 && logfd != 2)
-            close(logfd);
-    }
-
     gContext = new MythContext(MYTH_BINARY_VERSION, false);
     gContext->SetBackend(true);
 


More information about the mythtv-dev mailing list