File showconsole-1.16-glibc.dif of Package sysvinit

--- libconsole.c
+++ libconsole.c	2012-08-02 11:45:26.456510085 +0000
@@ -358,7 +358,9 @@ static void sigio(int sig)
  */
 
 typedef struct _mutex {
-    int locked;
+    volatile int locked;
+    volatile int canceled;
+    volatile int used;
     pthread_mutex_t mutex;
     pthread_t thread;
 } mutex_t;
@@ -380,8 +382,8 @@ static inline void unlock(mutex_t *mutex
     }
 }
 
-static mutex_t llock = { 0, PTHREAD_MUTEX_INITIALIZER, 0 };
-static mutex_t ljoin = { 0, PTHREAD_MUTEX_INITIALIZER, 0 };
+static mutex_t llock = { 0, 0, 1, PTHREAD_MUTEX_INITIALIZER, 0 };
+static mutex_t ljoin = { 0, 0, 1, PTHREAD_MUTEX_INITIALIZER, 0 };
 static pthread_cond_t lcond = PTHREAD_COND_INITIALIZER;
 static pthread_t    lthread;
 static volatile int running;
@@ -429,10 +431,14 @@ xout:
 
 static inline void writelog(void)
 {
+    int oldstate;
+
+    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
     lock(&llock);
     if (!flog) { /* log file closed, reset buffer */
 	resetlog();
 	unlock(&llock);
+	pthread_setcancelstate(oldstate, NULL);
 	return;
     }
     clearerr(flog);
@@ -468,11 +474,12 @@ static inline void writelog(void)
 	fflush(flog);
 	fdatasync(fileno(flog));
     }
+    pthread_setcancelstate(oldstate, NULL);
 }
 
 static inline void flushlog(void)
 {
-    if (running) pthread_cond_broadcast(&lcond);
+    if (ljoin.canceled == 0) pthread_cond_broadcast(&lcond);
 }
 
 static inline int poll(int msec, mutex_t *outer)
@@ -495,11 +502,13 @@ static inline int poll(int msec, mutex_t
 	    abstime.tv_nsec = now.tv_usec * 1000;
 
 	    do {
-		int locked = outer->locked;
 		/* Note: pthread_cond_timedwait() atomically unlocks the mutex */
-		outer->locked = 0;
-		err = pthread_cond_timedwait(&lcond, &outer->mutex, &abstime);
-		outer->locked = locked;
+		if (outer->canceled == 0) {
+		    volatile int locked = outer->locked;
+		    outer->locked = 0;
+		    err = pthread_cond_timedwait(&lcond, &outer->mutex, &abstime);
+		    outer->locked = locked;
+		}
 	    } while (err == EINTR);
 
 	    if (err == ETIMEDOUT || err == EBUSY)
@@ -507,9 +516,9 @@ static inline int poll(int msec, mutex_t
 	}
 #if 0
     } else {
-	unlock(&ljoin);
+	unlock(&outer->mutex);
 	pthread_yield();
-	lock(&ljoin);
+	lock(&outer->mutex);
 #endif
     }
 
@@ -789,6 +798,7 @@ static void *action(void *dummy attribut
     unlock(&ljoin);
 
     (void)pthread_sigmask(SIG_SETMASK, &save_oldset, NULL);
+    ljoin.used = 0;
     return NULL;
 }
 
@@ -1004,6 +1014,8 @@ void closeIO(void)
 	(void)tcdrain(c->fd);		/* Hold in sync with console */
     }
 
+    flushlog();
+
     do {
 	/*
 	 * Repeat this as long as required,
@@ -1020,14 +1032,19 @@ void closeIO(void)
     	more_input(&timeout, 1);
 	(void)tcdrain(fdread);
 
+	flushlog();
+
     } while (timeout.tv_sec || timeout.tv_nsec);
 
     if (running) {
 	lock(&ljoin);
 	running = 0;
 	unlock(&ljoin);
-	flushlog();
-	pthread_cancel(lthread);
+	ljoin.canceled = 1;
+	pthread_cond_broadcast(&lcond);
+	pthread_yield();
+	if (ljoin.used && lthread)
+	    pthread_cancel(lthread);
     }
 
     if (flog) {