From: Branden Robinson <branden@debian.org>
Subject: add support for logfile rotation

- Implement new ReopenLogFile() and ReopenLogFileNotify() functions.
  ReopenLogFileNotify() is a signal handler for SIGUSR2.
- Move the definition of the WRITES() macro from error.c to dm_error.h
  so that dm.c can use it as well.
- Document xdm's signal handling in its manpage.

Forward-ported by Eugene Konev and Julien Cristau.

Index: xdm/xdm/dm.c
===================================================================
--- xdm.orig/xdm/dm.c
+++ xdm/xdm/dm.c
@@ -90,8 +90,10 @@ from The Open Group.
 extern FILE    *fdopen();
 #endif
 
-static SIGVAL	StopAll (int n), RescanNotify (int n);
+static SIGVAL	StopAll (int n), RescanNotify (int n),
+				ReopenLogFileNotify (int n);
 static void	RescanServers (void);
+static void ReopenLogFile (void);
 static void	RestartDisplay (struct display *d, int forceReserver);
 static void	ScanServers (void);
 static void	SetAccessFileTime (void);
@@ -100,6 +102,7 @@ static void	StartDisplays (void);
 static void	TerminateProcess (pid_t pid, int signal);
 
 volatile int	Rescan;
+volatile int	Reopen;
 static long	ServersModTime, ConfigModTime, AccessFileModTime;
 
 int nofork_session = 0;
@@ -209,6 +212,7 @@ main (int argc, char **argv)
     AddOtherEntropy();
 #endif
     (void) Signal (SIGHUP, RescanNotify);
+    (void) Signal (SIGUSR2, ReopenLogFileNotify);
 #ifndef UNRELIABLE_SIGNALS
     (void) Signal (SIGCHLD, ChildNotify);
 #endif
@@ -219,6 +223,11 @@ main (int argc, char **argv)
 #endif
 	   AnyDisplaysLeft ())
     {
+	if (Reopen)
+	{
+	    ReopenLogFile ();
+		Reopen = 0;
+	}
 	if (Rescan)
 	{
 	    RescanServers ();
@@ -243,6 +252,7 @@ RescanNotify (int n)
     int olderrno = errno;
 
     Debug ("Caught SIGHUP\n");
+    Reopen = 1;
     Rescan = 1;
 #ifdef SIGNALS_RESET_WHEN_CAUGHT
     (void) Signal (SIGHUP, RescanNotify);
@@ -250,6 +260,26 @@ RescanNotify (int n)
     errno = olderrno;
 }
 
+/*
+ * Handle a SIGUSR2: set variable that will instruct the main loop to
+ * reopen the log file.
+ */
+static void
+ReopenLogFileNotify (int n)
+{
+#ifdef SIGNALS_RESET_WHEN_CAUGHT
+    int olderrno = errno;
+#endif
+
+    /* Debug() is not safe inside a signal handler. */
+    WRITES(STDERR_FILENO, "ReopenLogFileNotify handling SIGUSR2\n");
+    Reopen = 1;
+#ifdef SIGNALS_RESET_WHEN_CAUGHT
+    (void) Signal (SIGUSR2, ReopenLogFileNotify);
+    errno = olderrno;
+#endif
+}
+
 static void
 ScanServers (void)
 {
@@ -317,6 +347,14 @@ RescanServers (void)
 }
 
 static void
+ReopenLogFile (void)
+{
+    Debug ("closing standard error file descriptor %d\n", STDERR_FILENO);
+    close (STDERR_FILENO);
+    InitErrorLog ();
+}
+
+static void
 SetConfigFileTime (void)
 {
     struct stat	statb;
Index: xdm/include/dm_error.h
===================================================================
--- xdm.orig/include/dm_error.h
+++ xdm/include/dm_error.h
@@ -34,6 +34,8 @@ authorization.
 #ifndef _DM_ERROR_H_
 # define _DM_ERROR_H_ 1
 
+#define WRITES(fd, buf) write(fd, buf, strlen(buf))
+
 extern void Debug        (const char * fmt, ...) _X_ATTRIBUTE_PRINTF(1,2);
 extern void InitErrorLog (void);
 extern void LogAppend    (const char * fmt, ...) _X_ATTRIBUTE_PRINTF(1,2);
Index: xdm/man/xdm.man
===================================================================
--- xdm.orig/man/xdm.man
+++ xdm/man/xdm.man
@@ -1422,6 +1422,37 @@ isn't very good at doing is coexisting w
 multiple window systems on the same hardware, you'll probably be more
 interested in
 .I xinit.
+.SH "ASYNCHRONOUS EVENTS"
+.B xdm
+uses
+.B SIGALRM
+and
+.B SIGUSR1
+for its own inter-process communication purposes, managing the relationship
+between the parent
+.B xdm
+process and its children.
+Sending these signals to any
+.B xdm
+process may result in unexpected behavior.
+.TP
+.B SIGHUP
+causes
+.B xdm
+to rescan its configuration files and reopen its log file.
+.TP
+.B SIGTERM
+causes
+.B xdm
+to terminate its children and shut down.
+.TP
+.B SIGUSR2
+causes
+.B xdm
+to reopen its log file.
+This is useful if log rotation is desired, but
+.B SIGHUP
+is too disruptive.
 .SH FILES
 .TP 20
 .I XDMDIR/xdm-config
