util: fix file descriptor leak in mrafs-style logging
[openafs.git] / src / util / serverLog.c
index 55d483a..4ce8460 100644 (file)
@@ -73,10 +73,11 @@ char *serverLogSyslogTag = 0;
 int LogLevel;
 int mrafsStyleLogs = 0;
 static int threadIdLogs = 0;
-int printLocks = 0;
 static int resetSignals = 0;
 static char *ourName = NULL;
 
+static void RotateLogFile(void);
+
 void
 SetLogThreadNumProgram(int (*func) (void) )
 {
@@ -235,7 +236,6 @@ SetDebug_Signal(int signo)
             threadIdLogs = 0;
 #endif
     }
-    printLocks = 2;
 #if defined(AFS_PTHREAD_ENV)
     DebugOn((void *)(intptr_t)LogLevel);
 #else /* AFS_PTHREAD_ENV */
@@ -254,8 +254,6 @@ ResetDebug_Signal(int signo)
 {
     LogLevel = 0;
 
-    if (printLocks > 0)
-       --printLocks;
 #if defined(AFS_PTHREAD_ENV)
     DebugOn((void *)(intptr_t)LogLevel);
 #else /* AFS_PTHREAD_ENV */
@@ -272,11 +270,7 @@ ResetDebug_Signal(int signo)
         threadIdLogs = 0;
 #endif
     if (mrafsStyleLogs) {
-       LOCK_SERVERLOG();
-       if (ourName != NULL) {
-           OpenLog(ourName);
-       }
-       UNLOCK_SERVERLOG();
+       RotateLogFile();
     }
 }                              /*ResetDebug_Signal */
 
@@ -336,8 +330,6 @@ OpenLog(const char *fileName)
     int tempfd, isfifo = 0;
     int code;
     char *nextName = NULL;
-    struct timeval Start;
-    struct tm *TimeFields;
 
 #ifndef AFS_NT40_ENV
     struct stat statbuf;
@@ -366,24 +358,27 @@ OpenLog(const char *fileName)
     if (mrafsStyleLogs) {
         time_t t;
        struct stat buf;
-       gettimeofday(&Start, NULL);
-        t = Start.tv_sec;
-       TimeFields = localtime(&t);
-    makefilename:
-       code = asprintf(&nextName, "%s.%d%02d%02d%02d%02d%02d",
-                fileName, TimeFields->tm_year + 1900,
-                TimeFields->tm_mon + 1, TimeFields->tm_mday,
-                TimeFields->tm_hour, TimeFields->tm_min,
-                TimeFields->tm_sec);
-       if (code < 0) {
-           nextName = NULL;
-       } else if (lstat(nextName, &buf) == 0) {
-           /* avoid clobbering a log */
-           TimeFields->tm_sec++;
-           free(nextName);
-           nextName = NULL;
-           goto makefilename;
-       }
+       int tries;
+       struct tm *timeFields;
+
+       time(&t);
+       for (tries = 0; nextName == NULL && tries < 100; t++, tries++) {
+           timeFields = localtime(&t);
+           code = asprintf(&nextName, "%s.%d%02d%02d%02d%02d%02d",
+                    fileName, timeFields->tm_year + 1900,
+                    timeFields->tm_mon + 1, timeFields->tm_mday,
+                    timeFields->tm_hour, timeFields->tm_min,
+                    timeFields->tm_sec);
+           if (code < 0) {
+               nextName = NULL;
+               break;
+           }
+           if (lstat(nextName, &buf) == 0) {
+               /* Avoid clobbering a log. */
+               free(nextName);
+               nextName = NULL;
+           }
+        }
     } else {
        code = asprintf(&nextName, "%s.old", fileName);
        if (code < 0) {
@@ -465,6 +460,23 @@ ReOpenLog(const char *fileName)
 }
 
 /*!
+ * Rotate the log file by renaming then truncating.
+ */
+static void
+RotateLogFile(void)
+{
+    LOCK_SERVERLOG();
+    if (ourName != NULL) {
+       if (serverLogFD >= 0) {
+           close(serverLogFD);
+           serverLogFD = -1;
+       }
+       OpenLog(ourName);
+    }
+    UNLOCK_SERVERLOG();
+}
+
+/*!
  * Close the server log file.
  *
  * \note Must be preceeded by OpenLog().