File showconsole-1.13.dif of Package sysvinit.import4842

--- blogd.8
+++ blogd.8	2011-03-25 11:08:46.268426518 +0000
@@ -40,7 +40,7 @@ will not hold the real character device
 .I /dev/console
 as its controlling tty (would hangup any running
 getty on that character device).
-\."
+.\"
 .SH SIGNALS
 .B blogd
 knows a few signal to contol its behavior.
--- blogd.c
+++ blogd.c	2011-03-31 15:08:49.847926316 +0000
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <stropts.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <termios.h>
@@ -41,6 +42,8 @@
 #endif
 extern volatile sig_atomic_t nsigsys;
 
+static const char console[] = "/dev/console";
+
 /*
  * Internal logger
  */
@@ -91,7 +94,7 @@ static void rmfpid()
 /*
  * Write pidfile
  */
-static void pidfile()
+static void attribute((noinline)) pidfile()
 {
     char buf[strlen(_PATH_VARRUN)+strlen(myname)+1+3+1];
     FILE * fpid;
@@ -207,26 +210,55 @@ static void reconnect(int fd)
     }
 }
 
+
+static volatile int cntrtty = 1;
+static volatile pid_t pid = -1;
+static volatile pid_t ppid;
+
+static void flush_handler (void) attribute((noinline));
+static void exit_handler (void) attribute((noinline));
+
 /*
  * Now do the job
  */
 int main(int argc, char *argv[])
 {
-    int fd, flags;
-    int ptm, pts, cntrtty = 1;
-    const pid_t ppid = getppid();
-    const pid_t pgrp = getpgid(ppid);
     char ptsname[NAME_MAX+1];
     struct console *c;
     struct termios o;
     struct winsize w;
     struct stat st;
-    pid_t pid;
+    speed_t ospeed;
+    speed_t ispeed;
+    int ptm, pts;
+    int flags;
+    pid_t pgrp;
     time_t tt;
-    char *tty, *stt, *name = ttyname(0);
+    char *tty, *stt;
 
+    ppid = getppid();
+    pgrp = getpgid(ppid);
     myname = basename(*argv);
 
+    if (stat(console, &st) < 0)
+	error("No system console %s: %m\n", console);
+    else {
+	dev_t sysconsole = st.st_rdev;
+	int fd0;
+
+	if (stat("/proc/self/fd/0", &st) < 0)
+	    error("No standard input: %m\n");
+	if (sysconsole != st.st_rdev) {
+	    close(0);
+	    if ((fd0 = open(console, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0)
+		error("Can not open system console %s: %m\n", console);
+	    if (fd0 > 0) {
+		dup2(fd0, 0);
+		close(fd0);
+	    }
+	}
+    }
+
     if (argc > 2)
 	error("Too many args; usage: %s [/dev/tty<X>]\n", myname);
 
@@ -238,14 +270,8 @@ int main(int argc, char *argv[])
     if (!tty || !*tty)
 	error("can not discover real system console tty, boot logging disabled.\n");
 
-    if (!name || !*name) {
-	name = strdup("(no tty)");
-	if (!name)
-	    error("strdup(): %s\n", strerror(errno));
-    }
-
-    if (strcmp(tty, name) == 0)
-	error("console=%s, stdin=%s, must differ, boot logging disabled\n", tty, name);
+    if (strcmp(tty, console) == 0)
+	error("console=%s, stdin=%s, must differ, boot logging disabled\n", tty, console);
 
     if (posix_memalign((void*)&cons, sizeof(void*), alignof(typeof(struct console))) != 0)
 	error("memory allocation: %s\n", strerror(errno));
@@ -266,10 +292,14 @@ int main(int argc, char *argv[])
     if (tcgetattr(cons->fd, &cons->otio) < 0)
 	error("can not get terminal parameters of %s: %s\n", tty, strerror(errno));
 
-    if (fstat(cons->fd, &st) == 0 && major(st.st_rdev) == TTY_MAJOR) {
-	cfsetispeed(&cons->otio, B38400);
-	cfsetospeed(&cons->otio, B38400);
+    ispeed = B38400;
+    ospeed = B38400;
+    if (ioctl(cons->fd, TIOCMGET, &flags) == 0) {
+	ispeed = cfgetispeed(&cons->otio);
+	ospeed = cfgetospeed(&cons->otio);
     }
+    cfsetispeed(&cons->otio, ispeed);
+    cfsetospeed(&cons->otio, ospeed);
 
     if (tcgetpgrp(cons->fd) < 0)
 	cntrtty = 0;
@@ -286,6 +316,8 @@ int main(int argc, char *argv[])
 
     memcpy(&o, &cons->otio, sizeof(o));
     cfmakeraw(&o);
+    cfsetispeed(&o, ispeed);
+    cfsetospeed(&o, ospeed);
 
     if (openpty(&ptm, &pts, ptsname, &o, &w) < 0)
 	error("can not open pty/tty pair: %s\n", strerror(errno));
@@ -298,21 +330,43 @@ int main(int argc, char *argv[])
 	(void)ioctl(pts, TIOCSLCKTRMIOS, &lock);
     }
 
+    if (isastream(1) < 0 && errno == EBADF)
+	dup2(0, 1);
+    if (isastream(2) < 0 && errno == EBADF)
+	dup2(0, 2);
+
     secondtty(cons, st.st_rdev);
 
     (void)ioctl(0, TIOCCONS, NULL);  /* Undo any current map if any */
+    close(0);
+
     if (ioctl(pts, TIOCCONS, NULL) < 0)
 	error("can not set console device to %s: %s\n", ptsname, strerror(errno));
+    close(pts);
 
     for (c = cons; c; c = c->next) {
+	int iflag, oflag;
 #ifdef _PC_MAX_CANON
 	if ((c->max_canon = (ssize_t)fpathconf(c->fd, _PC_MAX_CANON)) <= 0)
 #endif
 	    c->max_canon = _POSIX_MAX_CANON;
 	c->tlock = 0;
-	if (tcgetattr(cons->fd, &cons->otio) < 0)
+	if (tcgetattr(c->fd, &c->otio) < 0)
 	    continue;
 	c->tlock = 1;
+#if 1
+	iflag = c->otio.c_iflag;
+	oflag = c->otio.c_oflag;
+
+	c->otio.c_iflag |= (ICRNL | IGNBRK);
+	c->otio.c_iflag &= ~(INLCR | IGNCR | BRKINT);
+	c->otio.c_oflag |= (ONLCR | OPOST);
+	c->otio.c_oflag &= ~(OCRNL | ONLRET);
+	(void)tcsetattr(c->fd, TCSADRAIN, &c->otio);
+
+	c->otio.c_iflag = iflag;
+	c->otio.c_oflag = oflag;
+#endif
 	if ((c->otio.c_lflag & ICANON) == 0) {
 	    c->otio.c_lflag |= ICANON | IEXTEN | ISIG | ECHO|ECHOE|ECHOK|ECHOKE;
 	    c->otio.c_oflag |= OPOST;
@@ -344,6 +398,8 @@ int main(int argc, char *argv[])
     (void)siginterrupt(SIGTERM, 0);
     (void)siginterrupt(SIGSYS,  0);
 
+    atexit(exit_handler);	/* Register main exit handler */
+
     switch ((pid = fork())) {
     case 0:
 	/* Get our own session */
@@ -352,55 +408,56 @@ int main(int argc, char *argv[])
 	dup2(ptm, 0);
 	dup2(cons->fd,  1);
 	dup2(cons->fd,  2);
-	if (cons->fd > 2) {
-	    close(cons->fd);
-	    cons->fd = 1;	/* Choose stdout */
-	}
-	close(pts);
+	if (cons->fd > 2)
+	    dup2(1, cons->fd);	/* Choose stdout */
 	close(ptm);
 	break;
     case -1:
-	close(pts);
 	close(ptm);
-	warn("can not fork to become daemon: %s\n", strerror(errno));
-	goto err;
+	error("can not fork to become daemon: %s\n", strerror(errno));
     default:
 	time(&tt);
 	stt = ctime(&tt);
-	close(pts);
 	close(ptm);
-	close(cons->fd);
-	cons->fd = -1;
 	for (c = cons; c; c = c->next) {
 	    if (c->fd > 0) {
 		close(c->fd);
 		c->fd = -1;
 	    }
 	}
-	fprintf(stdout, "\rBoot logging started on %s(%s) at %.24s\n", tty, name, stt);
+	fprintf(stdout, "\rBoot logging started on %s(%s) at %.24s\n", tty, console, stt);
 	fflush(stdout);
-	exit(0);
+	_exit(0);		/* NEVER rise exit handlers here */
     }
 
+    atexit(flush_handler);	/* Register flush exit handler */
+
     prepareIO(reconnect, pidfile, pgrp, 0);
     while (!signaled)
 	safeIO();
 
+    exit(0);			/* Raise exit handlers */
+}
+
+static void flush_handler (void)
+{
     (void)tcdrain(1);
     (void)tcdrain(2);
 
-    if (!cntrtty)
-	kill(ppid, SIGSTOP);
+    if (!cntrtty) kill(ppid, SIGSTOP);
     closeIO();
-    if (!cntrtty)
-	kill(ppid, SIGCONT);
+    if (!cntrtty) kill(ppid, SIGCONT);
+}
+
+static void exit_handler (void)
+{
+    struct console *c;
+    int fd;
 
-    (void)ioctl(0, TIOCSLCKTRMIOS, &o);
-err:
     for (c = cons; c; c = c->next) {
 	if (c->fd > 0) {
 	    if (c->tlock)	/* write back old setup  */
-		tcsetattr(c->fd, TCSANOW, &c->otio);
+		tcsetattr(c->fd, TCSADRAIN, &c->otio);
 	    if (c->tlock > 1)	/* write back lock if any */
 		(void)ioctl(c->fd, TIOCSLCKTRMIOS, &c->ltio);
 	    c->tlock = 0;
@@ -410,20 +467,15 @@ err:
     }
 
     errno = 0;
-    if ((fd = open("/dev/console", O_RDWR|O_NOCTTY)) >= 0) {
+    if ((fd = open(console, O_RDWR|O_NOCTTY)) >= 0) {
 	(void)ioctl(fd, TIOCCONS, NULL);	/* Restore old console mapping */
 	close(fd);
     }
 
-    if (pid > 0) {
-	(void)tcflush(1, TCOFLUSH);
-	close(1);
-	(void)tcflush(2, TCOFLUSH);
-	close(2);
-	(void)tcflush(0, TCIFLUSH);
-	close(0);
-	rmfpid();
-    }
+    close(1);
+    close(2);
+    (void)tcflush(0, TCIFLUSH);
+    close(0);
 
     reset_signal(SIGTTIN, &saved_sigttin);
     reset_signal(SIGTTOU, &saved_sigttou);
@@ -433,6 +485,4 @@ err:
     reset_signal(SIGQUIT, &saved_sigquit);
     reset_signal(SIGTERM, &saved_sigterm);
     reset_signal(SIGSYS,  &saved_sigsys);
-
-    return 0;
 }
--- libconsole.c
+++ libconsole.c	2011-03-25 11:11:22.040426359 +0000
@@ -29,6 +29,12 @@
 #include <sys/types.h> /* Defines the macros major and minor */
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#ifndef TIOCGDEV
+# include <sys/vt.h>
+# include <sys/kd.h>
+# include <linux/serial.h>
+#endif
+#include <linux/major.h>
 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/param.h>
@@ -52,9 +58,6 @@
 #include "libconsole.h"
 #include "listing.h"
 
-extern void error (const char *fmt, ...);
-extern void warn  (const char *fmt, ...);
-
 /*
  * push and popd direcotry changes
  */
@@ -110,12 +113,12 @@ static int rlstat(char ** file, struct s
 {
     int ret = -1;
     unsigned int deep = 0;
-    static ino_t iprev;			// Recurive loop detection
+    static ino_t iprev;			/* Recurive loop detection */
 
     if (lstat(*file, st) < 0)
 	goto out;
 
-    if (iprev && iprev == st->st_ino)	// We're run on the previous
+    if (iprev && iprev == st->st_ino)	/* We're run on the previous */
 	goto out;
     iprev = st->st_ino;
 
@@ -123,7 +126,7 @@ static int rlstat(char ** file, struct s
 	const char *prev_file;
 	ssize_t cnt;
 
-	if (!S_ISLNK(st->st_mode))	// Not a symlink
+	if (!S_ISLNK(st->st_mode))	/* Not a symlink */
 	    break;
 
 	if (deep++ > MAXSYMLINKS) {
@@ -175,7 +178,7 @@ static inline void safeout (int fd, cons
     static int eiocount;
 
     while (s > 0) {
-	ssize_t p = write (fd, ptr, (max < 0) ? s : ((s < (size_t)max) ? s : (size_t)max));
+	ssize_t p = write (fd, ptr, (max < 1) ? 1 : ((s < (size_t)max) ? s : (size_t)max));
 	if (p < 0) {
 	    if (errno == EPIPE) {
 		warn("error on writing to fd %d: %s\n", fd, strerror(errno));
@@ -238,6 +241,7 @@ static inline ssize_t safein (int fd, ch
     if (s > SSIZE_MAX)
 	s = SSIZE_MAX;
 
+    t=0;
     if ((ioctl(fd, FIONREAD, &t) < 0) || (t == 0)) {
 	fd_set check;
 	struct timeval zero = {0, 0};
@@ -258,6 +262,8 @@ static inline ssize_t safein (int fd, ch
 	if (r < 0 && errno != EPIPE) {
 	    if (noerr)
 		goto out;
+	    if (fd == 0 && errno == EIO)
+		warn("\e[31m\e[1msystem console stolen at line %d!\e[m\n", __LINE__);
 	    error("Can not read from fd %d: %s\n", fd, strerror(errno));
 	}
 
@@ -279,6 +285,8 @@ static inline ssize_t safein (int fd, ch
 	    }
 	    if (noerr)
 		goto out;
+	    if (fd == 0 && errno == EIO)
+		warn("\e[31m\e[1msystem console stolen at line %d!\e[m\n", __LINE__);
 	    error("Can not read from fd %d: %s\n", fd, strerror(errno));
 	}
 	repeated = 0;
@@ -707,11 +715,12 @@ static void parselog(unsigned char *buf,
 static void copylog(const unsigned char *buf, const size_t s)
 {
     lock(&llock);
-    if (!nl) {
+    if (!nl)
 	addlog('\n');
-	nl = 1;
-    }
     storelog(buf, s);
+    if (buf[s-1] != '\n')
+	addlog('\n');
+    nl = 1;
     unlock(&llock);
 }
 
@@ -770,7 +779,7 @@ void prepareIO(void (*rfunc)(int), void
 	    (void)mkfifo(fifo_name, 0600);
 	errno = 0;
 	if (!stat(fifo_name, &st) && S_ISFIFO(st.st_mode)) {
-	    if ((fdfifo = open(fifo_name, O_RDONLY|O_NOCTTY|O_CLOEXEC)) < 0)
+	    if ((fdfifo = open(fifo_name, O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
 		warn("can not open named fifo %s: %s\n", fifo_name, strerror(errno));
 	}
     }
@@ -1141,6 +1150,15 @@ static int checkdev(char ** retname, con
 	    if (!strncmp(name, "ram", 3))
 		continue;
 
+	    if (!strncmp(name, "rtc", 3))
+		continue;
+
+	    if (!strncmp(name, "card", 4))
+		continue;
+
+	    if (!strncmp(name, "vboxguest", 9))
+		continue;
+
 	    if (!strcmp(name, "cciss"))
 		continue;
 
@@ -1183,8 +1201,23 @@ static int checkdev(char ** retname, con
 	    if (!strcmp(name, "block"))
 		continue;
 
+	    if (!strcmp(name, "cgroup"))
+		continue;
+
 	    if (!strcmp(name, "disk"))
 		continue;
+
+	    if (!strcmp(name, "bus"))
+		continue;
+
+	    if (!strcmp(name, "bsg"))
+		continue;
+
+	    if (!strcmp(name, "cpu"))
+		continue;
+
+	    if (!strcmp(name, "char"))
+		continue;
 	}
 
 	if (rlstat(&name, &st) < 0) {
@@ -1251,37 +1284,50 @@ static int checkdev(char ** retname, con
 /* main routine to fetch tty */
 char * fetchtty(const pid_t pid, const pid_t ppid, dev_t * tty)
 {
-#ifdef TIOCGDEV
-    unsigned int mjmi = 0;
-#endif
     char * name = NULL;
     dev_t dev = 0;
     int found = 0;
     DIR * ddev;
     FILE * fc;
 
-    if ((fc = fopen("/proc/tty/consoles", "r"))) {
+    if ((fc = fopen("/proc/consoles", "r"))) {
 	char fbuf[16];
 	int maj, min;
 	while ((fscanf(fc, "%*s %*s (%[^)]) %d:%d", &fbuf[0], &maj, &min) == 3)) {
 	    if (!strchr(fbuf, 'E'))
 		continue;
-	    if (strchr(fbuf, '*')) {
+	    if (strchr(fbuf, 'C')) {
 		dev = makedev(maj, min);
 		break;
 	    }
 	}
 	fclose(fc);
-    }
+    } else {
 #ifdef TIOCGDEV
-    else {
-	if (ioctl (0, TIOCGDEV, &mjmi) < 0) {
+	unsigned int devnum = 0;
+	if (ioctl (0, TIOCGDEV, &devnum) < 0) {
 	    if (errno == EINVAL && !getenv("NOTIOCGDEV"))
 		warn("Warning: the ioctl TIOCGDEV is not known by the kernel\n");
 	}
-	dev = (dev_t)mjmi;
-    }
+	dev = (dev_t)devnum;
+#else
+	struct stat st;
+	if (fstat(0, &st) == 0 && (major(st.st_rdev) == TTYAUX_MAJOR || st.st_rdev == makedev(TTY_MAJOR, 0))) {
+	    unsigned int arg;
+	    if (ioctl(0, TIOCMGET, &arg) == 0) {		/* serial line */
+# if 0
+		dev = makedev(TTY_MAJOR, 64);			/* 8250/16450/16550(A) ports */
+# else
+		dev = 0;
+# endif
+	    } else if (ioctl(0, KDGKBTYPE, &arg) == 0) {	/* virtual console */
+		struct vt_stat vt;
+		if (ioctl(0, VT_GETSTATE, &vt) == 0)
+		    dev = makedev(TTY_MAJOR, (int)vt.v_active);
+	    }
+	}
 #endif
+    }
     if (!dev) {
 	if (!(name = ttyname(0)) || !strcmp(name, "/dev/console"))
 	    dev = fallback(pid, ppid);
@@ -1327,8 +1373,9 @@ void secondtty(struct console *restrict
 
     tail = cons;
 
-    if ((fc = fopen("/proc/tty/consoles", "r"))) {
-	int maj, min, flags;
+    if ((fc = fopen("/proc/consoles", "r"))) {
+	unsigned int maj, min;
+	int flags;
 	struct stat st;
 	char fbuf[16];
 
@@ -1341,13 +1388,13 @@ void secondtty(struct console *restrict
 	    error("can not opendir(/dev): %s\n", strerror(errno));
 	pushd("/dev");
 
-	while ((fscanf(fc, "%*s %*s (%[^)]) %d:%d", &fbuf[0], &maj, &min) == 3)) {
+	while ((fscanf(fc, "%*s %*s (%[^)]) %u:%u", &fbuf[0], &maj, &min) == 3)) {
 	    struct console *restrict newc;
 	    dev_t dev;
 
 	    if (!strchr(fbuf, 'E'))
 		continue;
-	    if (strchr(fbuf, '*'))
+	    if (strchr(fbuf, 'C'))
 		continue;
 	    dev = makedev(maj, min);
 
@@ -1379,14 +1426,14 @@ void secondtty(struct console *restrict
 
 	    if ((flags = fcntl(newc->fd, F_GETFL)) < 0) {
 		warn("can not get terminal flags of %s: %s\n", newc->tty, strerror(errno));
+		free(newc);
 		continue;
 	    }
 
 	    flags &= ~(O_NONBLOCK);
 	    flags |=   O_NOCTTY;
-	    if (fcntl(newc->fd, F_SETFL, flags) < 0) {
+	    if (fcntl(newc->fd, F_SETFL, flags) < 0)
 		warn("can not set terminal flags of %s: %s\n", newc->tty, strerror(errno));
-	    }
 	}
 
 	popd();
@@ -1433,7 +1480,12 @@ void secondtty(struct console *restrict
 	struct console *restrict newc;
 	char *res = (char*)0;
 	struct stat st;
-	int flags;
+#ifdef TIOCGDEV
+	unsigned int devnum;
+#else
+	struct vt_stat vt;
+#endif
+	int fd, flags;
 
 	if (*ptr == ',' || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') {
 	    *ptr-- = 0;
@@ -1461,14 +1513,47 @@ void secondtty(struct console *restrict
 	if (!res)
 	    continue;
 
-	if (stat(res, &st) < 0) {
-	    warn("can not stat /dev/%s: %s\n", res, strerror(errno));
+	/* Open second console e.g. /dev/tty0 */
+	if ((fd = open(res, O_RDWR|O_NONBLOCK|O_NOCTTY)) < 0)
+	    continue;
+
+	/*
+	 * We do this because if we would write out the buffered
+	 * messages to e.g. /dev/tty0 after this we would (re)read
+	 * those and buffer them again which leads to an endless loop.
+	 */
+#ifdef TIOCGDEV
+	if (ioctl (fd, TIOCGDEV, &devnum) < 0) {
+	    if (errno == EINVAL && !getenv("NOTIOCGDEV"))
+		warn("Warning: the ioctl TIOCGDEV is not known by the kernel\n");
+	    close(fd);
+	    continue;
+	}
+	st.st_rdev = (dev_t)devnum;
+#else
+	if (fstat(fd, &st) < 0) {
+	    close(fd);
 	    continue;
 	}
 
+	if (st.st_rdev == makedev(TTY_MAJOR, 0)) {
+	    if (ioctl(fd, VT_GETSTATE, &vt) < 0) {
+		if (errno == EINVAL)
+		    warn("Warning: the ioctl VT_GETSTATE is not known by the kernel\n");
+		close(fd);
+		continue;
+	    }
+	    st.st_rdev = makedev(TTY_MAJOR, (int)vt.v_active);
+	}
+#endif
+	close(fd);
+
 	if (st.st_rdev == tty)
 	    continue;
 
+	if (st.st_rdev == makedev(TTY_MAJOR, 0))	/* Avoid endless loop */
+	    continue;
+
 	if (!checkdev(&name, st.st_rdev, ddev) || !name) {
 	    if (name) {
 		free(name);
@@ -1492,14 +1577,14 @@ void secondtty(struct console *restrict
 
 	if ((flags = fcntl(newc->fd, F_GETFL)) < 0) {
 	    warn("can not get terminal flags of %s: %s\n", newc->tty, strerror(errno));
+	    free(newc);
 	    continue;
 	}
 
 	flags &= ~(O_NONBLOCK);
 	flags |=   O_NOCTTY;
-	if (fcntl(newc->fd, F_SETFL, flags) < 0) {
+	if (fcntl(newc->fd, F_SETFL, flags) < 0)
 	    warn("can not set terminal flags of %s: %s\n", newc->tty, strerror(errno));
-	}
     }
 
     popd();
--- libconsole.h
+++ libconsole.h	2011-03-25 11:08:46.344426335 +0000
@@ -27,6 +27,9 @@
 # ifndef  extension
 #  define extension		__extension__
 # endif
+# ifndef  typeof
+#  define typeof		__typeof__
+# endif
 #endif
 #ifndef  attribute
 # define attribute(attr)	__attribute__(attr)
@@ -38,6 +41,8 @@ struct console {
     struct termios ltio, otio;
     struct console *restrict next;
 };
+extern void error (const char *fmt, ...) attribute((__noreturn__, __format__(__printf__, 1, 2)));
+extern void warn  (const char *fmt, ...) attribute((__format__(__printf__, 1, 2)));
 extern void pushd(const char *);
 extern void popd(void);
 extern char * fetchtty(const pid_t, const pid_t, dev_t *);
--- showconsole.8
+++ showconsole.8	2010-11-09 15:26:29.038362757 +0000
@@ -22,8 +22,7 @@ Setconsole \- redirect system console ou
 .SH DESCRIPTION
 .B showconsole
 determines the real character device of
-the current
-.BR stdin.
+the current system console.
 This can be used on
 .I /dev/console
 as current character device to
--- showconsole.c
+++ showconsole.c	2010-10-25 13:08:25.583937937 +0000
@@ -19,6 +19,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <signal.h>
 #include "libconsole.h"
 
 /*
openSUSE Build Service is sponsored by