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