SOURCES: showconsole-suse.patch (NEW) - from suse sysvinit package

glen glen at pld-linux.org
Tue Oct 30 23:54:43 CET 2007


Author: glen                         Date: Tue Oct 30 22:54:43 2007 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- from suse sysvinit package

---- Files affected:
SOURCES:
   showconsole-suse.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/showconsole-suse.patch
diff -u /dev/null SOURCES/showconsole-suse.patch:1.1
--- /dev/null	Tue Oct 30 23:54:43 2007
+++ SOURCES/showconsole-suse.patch	Tue Oct 30 23:54:38 2007
@@ -0,0 +1,599 @@
+--- blogd.c
++++ blogd.c	2006-08-10 18:41:55.000000000 +0200
+@@ -155,25 +155,60 @@ static void reset_signal(int sig, struct
+  * To be able to reconnect to real tty on EIO
+  */
+ static char * tty;
++static char * second;
+ static void reconnect(int fd)
+ {
+     int newfd = -1;
+ 
+-    if ((newfd = open(tty, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0)
+-	error("can not open %s: %s\n", tty, strerror(errno));
+- 
+-    if (newfd != 1)
+-	dup2(newfd,  1);
+-    if (newfd != 2)
+-	dup2(newfd,  2);
+-
+-    if (fd == 1 || fd == 2)
+-	goto out;
+-    if (newfd != fd)
+-	dup2(newfd, fd);
+-out:
+-    if (newfd > 2)
+-	close(newfd);
++    switch (fd) {
++    case 0:		/* Standard in */
++
++	if (tty == (char*)0)
++	    break;
++
++	if ((newfd = open(tty, O_RDWR|O_NONBLOCK|O_NOCTTY)) < 0)
++	    error("can not open %s: %s\n", tty, strerror(errno));
++
++	if (newfd != 0) {
++	    dup2(newfd, 0);
++	    close(newfd);
++	}
++
++	break;
++
++    case 1:		/* Standard out */
++    case 2:		/* Standard error */
++
++	if (tty == (char*)0)
++	    break;
++
++	if ((newfd = open(tty, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0)
++	    error("can not open %s: %s\n", tty, strerror(errno));
++
++	if (newfd != 1)
++	    dup2(newfd,  1);
++	if (newfd != 2)
++	    dup2(newfd,  2);
++	if (newfd > 2)
++	    close(newfd);
++
++	break;
++
++    default:		/* IO of second console */
++
++	if (second == (char*)0)
++	    break;
++
++	if ((newfd = open(second, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0)
++	    error("can not open %s: %s\n", second, strerror(errno));
++
++	if (newfd != fd) {
++	    dup2(newfd, fd);
++	    close(newfd);
++	}
++
++	break;
++    }
+ }
+ 
+ /*
+@@ -181,7 +216,7 @@ out:
+  */
+ int main(int argc, char *argv[])
+ {
+-    int fd, flags;
++    int fd, fd2, flags;
+     int ptm, pts, cntrtty = 1;
+     pid_t pid, ppid = getppid();
+     char ptsname[NAME_MAX+1];
+@@ -198,7 +233,7 @@ int main(int argc, char *argv[])
+     if (argc == 2)
+ 	tty = argv[1];
+     else
+-	tty = fetchtty(getpid(), ppid);
++	tty = fetchtty(getpid(), ppid, NULL);
+ 
+     if (!tty || !*tty)
+ 	error("can not discover real system console tty, boot logging disabled.\n");
+@@ -241,6 +276,38 @@ int main(int argc, char *argv[])
+     if (!w.ws_col)
+ 	w.ws_row = 80;
+ 
++    fd2 = -1;
++    do {
++
++	if ((second = secondtty(tty)) == (char*)0)
++	    break;
++
++	if ((fd2 = open(second, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0) {
++	    warn("can not open %s: %s\n", second, strerror(errno));
++	    goto out;
++	}
++
++	if ((flags = fcntl(fd2, F_GETFL)) < 0) {
++	    warn("can not get terminal flags of %s: %s\n", second, strerror(errno));
++	    close(fd2);
++	    fd2 = -1;
++	    goto out;
++	}
++
++	flags &= ~(O_NONBLOCK);
++	flags |=   O_NOCTTY;
++	if (fcntl(fd2, F_SETFL, flags) < 0) {
++	    warn("can not set terminal flags of %s: %s\n", second, strerror(errno));
++	    close(fd2);
++	    fd2 = -1;
++	    goto out;
++	}
++
++    out:
++	free(second);
++	
++    } while (0);
++
+     if (openpty(&ptm, &pts, ptsname, &t, &w) < 0)
+ 	error("can not open pty/tty pair: %s\n", strerror(errno));
+ 
+@@ -268,12 +335,15 @@ int main(int argc, char *argv[])
+ 	dup2(fd,  1);
+ 	dup2(fd,  2);
+ 	close(ptm);
+-	close(fd);
++	if (fd > 2)
++	    close(fd);
+ 	break;
+     case -1:
+ 	close(pts);
+ 	close(ptm);
+ 	close(fd);
++	if (fd2 > 0)
++	    close(fd2);
+ 	error("can not fork to become daemon: %s\n", strerror(errno));
+ 	break;
+     default:
+@@ -282,12 +352,13 @@ int main(int argc, char *argv[])
+ 	close(pts);
+ 	close(ptm);
+ 	close(fd);
++	if (fd2 > 0)
++	    close(fd2);
+ 	fprintf(stdout, "\rBoot logging started on %s(%s) at %.24s\n", tty, name, stt);
+ 	fflush(stdout);
+ 	exit(0);
+     }
+-    free(name);
+-    prepareIO(reconnect, pidfile, 0, 1);
++    prepareIO(reconnect, pidfile, 0, 1, fd2);
+     while (!signaled)
+ 	safeIO();
+ 
+@@ -297,6 +368,10 @@ int main(int argc, char *argv[])
+     if (!cntrtty)
+ 	kill(ppid, SIGCONT);
+ 
++    if (fd2 > 0) {
++	(void)tcflush(fd2, TCOFLUSH);
++	close(fd2);
++    }
+     (void)tcflush(1, TCOFLUSH);
+     close(1);
+     (void)tcflush(2, TCOFLUSH);
+--- libconsole.c
++++ libconsole.c	2006-08-10 18:41:23.000000000 +0200
+@@ -158,41 +158,52 @@ static void (*vc_reconnect)(int fd) = NU
+ static inline void safeout (int fd, const char *ptr, size_t s)
+ {
+     int saveerr = errno;
+-    static int repeated;
++    int repeated = 0;
++    static int eiocount;
+ 
+-    repeated = 0;
+     while (s > 0) {
+ 	ssize_t p = write (fd, ptr, s);
+ 	if (p < 0) {
+-	    if (repeated++ > 1000)
+-		error("Repeated error on writing to fd %d: %s\n", fd, STRERR);
+-	    if (errno == EPIPE)
++	    if (errno == EPIPE) {
++		warn("error on writing to fd %d: %s\n", fd, STRERR);
+ 		exit (0);
++	    }
+ 	    if (errno == EINTR) {
+ 		errno = 0;
+ 		continue;
+ 	    }
+ 	    if (errno == EAGAIN) {	/* Kernel 2.6 seems todo this very often */
++		int ret;
+ 		fd_set check;
+-		struct timeval two = {2, 0};
+ 
+-		errno = 0;
++		if (repeated++ > 1000)
++		    error("repeated error on writing to fd %d: %s\n", fd, STRERR);
++
+ 		FD_ZERO (&check);
+ 		FD_SET (fd, &check);
+ 
+ 		/* Avoid high load: wait upto two seconds if system is not ready */
+-		select(fd + 1, (fd_set*)0, &check, (fd_set*)0, &two);
+ 		errno = 0;
++		do {
++		    struct timeval two = {2, 0};
++		    ret = select(fd + 1, (fd_set*)0, &check, (fd_set*)0, &two);
++
++		} while ((ret < 0) && (errno == EINTR));
++
++		if (ret < 0)
++		    error("can not write to fd %d: %s\n", fd, STRERR);
+ 
++		errno = 0;
+ 		continue;
+ 	    }
+-	    if (errno == EIO && vc_reconnect) {
++	    if (errno == EIO) {
++		if ((eiocount++ > 10) || !vc_reconnect)
++		    error("can not write to fd %d: %s\n", fd, STRERR);
+ 		(*vc_reconnect)(fd);
+-		vc_reconnect = NULL;
+ 		errno = 0;
+ 		continue;
+ 	    }
+-	    error("Can not write to fd %d: %s\n", fd, STRERR);
++	    error("can not write to fd %d: %s\n", fd, STRERR);
+ 	}
+ 	repeated = 0;
+ 	ptr += p;
+@@ -267,6 +278,7 @@ out:
+  */
+ static FILE * flog = NULL;
+ static int fdwrite = -1;
++static int fdsec   = -1;
+ static int fdread  = -1;
+ static int fdfifo  = -1;
+ 
+@@ -714,12 +726,13 @@ static void *action(void *dummy)
+ static void (*rw_connect)(void) = NULL;
+ static const char *fifo_name = _PATH_BLOG_FIFO;
+ 
+-void prepareIO(void (*rfunc)(int), void (*cfunc)(void), const int in, const int out)
++void prepareIO(void (*rfunc)(int), void (*cfunc)(void), const int in, const int out, const int second)
+ {
+     vc_reconnect = rfunc;
+     rw_connect   = cfunc;
+     fdread  = in;
+     fdwrite = out;
++    fdsec   = second;
+ 
+     if (fifo_name && fdfifo < 0) {
+ 	struct stat st;
+@@ -729,7 +742,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_RDWR)) < 0)
++	    if ((fdfifo = open(fifo_name, O_RDWR|O_NOCTTY)) < 0)
+ 		warn("can not open named fifo %s: %s\n", fifo_name, STRERR);
+ 	}
+     }
+@@ -769,12 +782,17 @@ static void more_input (struct timeval *
+ 	const ssize_t cnt = safein(fdread, (char*)trans, sizeof(trans));
+ 
+ 	if (cnt > 0) {
+-	     parselog(trans, cnt);		/* Parse and make copy of the input */
++	    parselog(trans, cnt);		/* Parse and make copy of the input */
++
++	    safeout(fdwrite, (char*)trans, cnt);	/* Write copy of input to real tty */
++	    (void)tcdrain(fdwrite);
+ 
+-	     safeout(fdwrite, (char*)trans, cnt);	/* Write copy of input to real tty */
+-	     tcdrain(fdwrite);
++	    if (fdsec > 0) {
++		safeout(fdsec, (char*)trans, cnt);	/* Write copy of input to second tty */
++		(void)tcdrain(fdsec);
++	    }
+ 
+-	     flushlog();
++	    flushlog();
+ 	}
+     }
+ 
+@@ -883,6 +901,8 @@ void closeIO(void)
+     } else
+ 	warn("no message logging because /var file system is not accessible\n");
+     (void)tcdrain(fdwrite);		/* Hold in sync with console */
++    if (fdsec > 0)
++	(void)tcdrain(fdsec);		/* Hold in sync with second console */
+ 
+     do {
+ 	/*
+@@ -926,6 +946,8 @@ void closeIO(void)
+     flog = NULL;
+ xout:
+     (void)tcdrain(fdwrite);
++    if (fdsec > 0)
++	(void)tcdrain(fdsec);
+ 
+     return;
+ }
+@@ -941,7 +963,7 @@ static void ctty(pid_t pid, unsigned int
+     int fd;
+ 
+     sprintf(fetched, "/proc/%d/stat", (int)pid);
+-    if ((fd = open(fetched, O_RDONLY)) < 0)
++    if ((fd = open(fetched, O_RDONLY|O_NOCTTY)) < 0)
+ 	error("can not open(%s): %s\n", fetched, STRERR);
+     cnt = safein(fd, fetched, sizeof(fetched));
+     close(fd);
+@@ -1034,12 +1056,11 @@ static int checkdev(char ** retname, uns
+     int found = 0;
+     struct dirent * d;
+     struct stat st;
+-    char * name = NULL;
+     static int deep;
+ 
+     memset(&st, 0, sizeof(struct stat));
+     while ((d = readdir(dev))) {
+-	name = d->d_name;
++	char * name = d->d_name;
+ 
+ 	if (*name == '.')
+ 	    continue;
+@@ -1143,6 +1164,14 @@ static int checkdev(char ** retname, uns
+ 	}
+ 
+ 	found++;
++
++	/*
++	 * Allocate memory to be able to return several
++	 * different buffers for different files names.
++	 */
++	name = strdup(name);
++	if (!name)
++	    error("checkdev(): %s\n", STRERR);
+ 	*retname = name;
+ 	break;
+     }
+@@ -1151,7 +1180,7 @@ static int checkdev(char ** retname, uns
+ }
+ 
+ /* main routine to fetch tty */
+-char * fetchtty(const pid_t pid, const pid_t ppid)
++char * fetchtty(const pid_t pid, const pid_t ppid, unsigned int *mjmi)
+ {
+     unsigned int tty = 0, found = 0;
+     char * name = NULL;
+@@ -1167,14 +1196,15 @@ char * fetchtty(const pid_t pid, const p
+ 	if (!(name = ttyname(0)) || !strcmp(name, "/dev/console"))
+ 	    tty = fallback(pid, ppid);
+ 	else {
+-	    strcpy(lnk, name);
+-	    free(name);
+-	    name = lnk;
++	    name = strdup(name);
++	    if (!name)
++		error("fetchtty(): %s\n", STRERR);
+ 	    goto out;
+ 	}
+ #ifdef TIOCGDEV
+     }
+ #endif
++    if (mjmi) *mjmi = tty;
+ 
+     if (!(dev = opendir("/dev")))
+ 	error("can not opendir(/dev): %s\n", STRERR);
+@@ -1186,8 +1216,131 @@ char * fetchtty(const pid_t pid, const p
+     if (!name)
+ 	goto out;
+ 
+-    if (!found)
+-	*name = '\0';
++    if (!found) {
++	free(name);
++	name = (char*)0;
++    }
+ out:
+     return name;
+ }
++
++/* Do we have some more system console around? */
++char * secondtty(char * compare)
++{
++    char buf[1024], *ptr, *shcmp, *res = (char*)0;
++    unsigned int tty = 0, found = 0;
++    int fd = -1, len;
++    char * name = (char*)0;
++    DIR * dev;
++
++    if ((fd = open("/proc/cmdline", O_RDONLY|O_NOCTTY)) < 0) {
++	warn("can not open /proc/cmdline\n");
++	goto out;
++    }
++
++    if ((len = read(fd, buf, sizeof(buf) - 1)) < 0) {
++	warn("can not read /proc/cmdline\n");
++	close(fd);
++	goto out;
++    }
++    close(fd);
++
++    if (len == 0)
++	goto out;
++
++    shcmp = compare;
++    if (!strncmp(shcmp, "/dev/", 5))
++	shcmp += 5;
++
++    /*
++     * Check for e.g. /dev/tty[1-9] which is equal to /dev/tty0
++     */
++    if (!strncmp(shcmp, "tty", 3)) {
++	size_t len = strspn(shcmp + 3, "123456789");
++
++	if (strlen(shcmp) == len + 3) {
++	    compare = "/dev/tty0";
++	    shcmp   = "tty0";
++	}
++    }
++
++    ptr = &buf[len];
++    while (ptr >= &buf[0]) {
++	if (*ptr == ',' || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') {
++	    *ptr-- = 0;
++	    continue;
++	}
++	if (*ptr == 'c' && !strncmp(ptr, "console=", 8)) {
++	    char * console  = ptr + 8;
++
++	    if (!strncmp(console, "/dev/", 5))
++		console += 5;
++
++	    /*
++	     * Compare known console tty with that of the kernel command
++	     * line.  If already known skip this console tty and search
++	     * for the next one.
++	     */
++	    if (strcmp(shcmp, console)) {
++		res = console;		/* New device not identical to tty */
++		break;
++	    }
++	}
++	ptr--;
++    }
++
++    if (!res)
++	goto out;
++
++    if (!(dev = opendir("/dev")))
++	error("can not opendir(/dev): %s\n", STRERR);
++    pushd("/dev");
++
++    /* Open second console e.g. /dev/tty0 */
++    if ((fd = open(res, O_RDWR|O_NONBLOCK|O_NOCTTY)) < 0)
++	goto out;
++
++    /*
++     * 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, &tty) < 0) {
++	if (errno == EINVAL && !getenv("NOTIOCGDEV"))
++	    warn("Warning: the ioctl TIOCGDEV is not known by the kernel\n");
++	close(fd);
++	popd();
++	closedir(dev);
++	goto out;
++    }
++#else
++#   error The ioctl TIOCGDEV is not defined (SuSE TIOCGDEV patch is missed)
++#endif
++    close(fd);
++
++    /* Try to open the real device e.g. /dev/tty1 */
++    found = checkdev(&name, tty, dev);
++
++    popd();
++    closedir(dev);
++
++    if (!name)
++	goto out;
++
++    if (!found) {
++	free(name);
++	name = (char*)0;
++	goto out;
++    }
++
++    if (!strcmp(compare, name)) {
++	free(name);
++	name = (char*)0;
++	goto out;		/* Already in use */
++    }
++
++    return name;
++out:
++    return (char*)0;
++}
+--- libconsole.h
++++ libconsole.h	2006-08-10 18:41:28.000000000 +0200
+@@ -1,6 +1,7 @@
+ extern void pushd(const char * path);
+ extern void popd(void);
+-extern char * fetchtty(const pid_t pid, const pid_t ppid);
+-extern void prepareIO(void (*rfunc)(int), void (*cfunc)(void), const int in, const int out);
++extern char * fetchtty(const pid_t pid, const pid_t ppid, unsigned int *mjmi);
++extern char * secondtty(char * compare);
++extern void prepareIO(void (*rfunc)(int), void (*cfunc)(void), const int in, const int out, const int second);
+ extern void safeIO (void);
+ extern void closeIO(void);
+--- showconsole.8
++++ showconsole.8	2006-08-10 18:55:37.000000000 +0200
+@@ -16,6 +16,7 @@ Setconsole \- sets the underlying tty of
+ .SH SYNOPSIS
+ .\"
+ .B showconsole
++.RI [ -n ]
+ .PP
+ .B setconsole /dev/tty<xy> < /dev/console
+ .SH DESCRIPTION
+@@ -38,6 +39,15 @@ with
+ and exactly one argument, a valid character device
+ is given.
+ \."
++.SH OPTIONS
++.TP
++.B \-n
++Return the major and minor device numbers instead of
++the device file name.  This can be used to asked the
++kernel for the major and minor device numbers of a not
++existing device file in
++.IR /dev .
++\."
+ .SH BUGS
+ .B showconsole
+ needs a mounted
+--- showconsole.c
++++ showconsole.c	2006-08-10 18:51:15.000000000 +0200
+@@ -51,7 +51,7 @@ void warn (const char *fmt, ...)
+  */
+ int main(int argc, char *argv[])
+ {
+-    char * tty = NULL;
++    char * tty = NULL, numeric = 0;
+     myname = basename(*argv);
+ 
+     if (!strcmp(myname, "setconsole")) {
+@@ -73,8 +73,30 @@ int main(int argc, char *argv[])
+ 	close(fdc);
+ 	goto out;
+     }
+-    tty = fetchtty(getpid(), getppid());
+-    if (tty)
++
++    if (argc == 2) {
++	const char* opt = argv[1];
++	if (opt && *opt++ == '-' && *opt++ == 'n' && *opt == '\0')
++	    numeric++;
++	else
++	    error("Usage: %s [-n]\n", myname);
++    } else if (argc > 2)
++	error("Usage: %s [-n]\n", myname);
++
++    if (numeric) {
++	unsigned int dev = 0;
++	(void)fetchtty(getpid(), getppid(), &dev);
++
++	if (dev)
++	    printf("%u %u\n", major(dev), minor(dev));
++	else {
++	    error("real tty unknown\n");
++	    fprintf(stderr, "real tty unknown\n");
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list