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>>
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to