diff --git a/src/bootlogd.c b/src/bootlogd.c index e64bffb..a5428ff 100644 --- a/src/bootlogd.c +++ b/src/bootlogd.c @@ -57,6 +57,7 @@ char *Version = "@(#) bootlogd 2.86 03-Jun-2004 miquels@cistron.nl"; #define LOGFILE "/var/log/boot" +#define MAX_CONSOLES 16 char ringbuf[32768]; char *endptr = ringbuf + sizeof(ringbuf); @@ -68,6 +69,11 @@ int didnl = 1; int createlogfile = 0; int syncalot = 0; +struct real_cons { + char name[1024]; + int fd; +}; + /* * Console devices as listed on the kernel command line and * the mapping to actual devices in /dev @@ -230,10 +236,10 @@ int isconsole(char *s, char *res, int rlen) } /* - * Find out the _real_ console. Assume that stdin is connected to + * Find out the _real_ console(s). Assume that stdin is connected to * the console device (/dev/console). */ -int consolename(char *res, int rlen) +int consolenames(struct real_cons *cons, int max_consoles) { #ifdef TIOCGDEV unsigned int kdev; @@ -242,34 +248,9 @@ int consolename(char *res, int rlen) char buf[256]; char *p; int didmount = 0; - int n, r; + int n; int fd; - - fstat(0, &st); - if (major(st.st_rdev) != 5 || minor(st.st_rdev) != 1) { - /* - * Old kernel, can find real device easily. - */ - int r = findtty(res, "/dev", rlen, st.st_rdev); - if (0 != r) - fprintf(stderr, "bootlogd: cannot find console device " - "%d:%d under /dev\n", major(st.st_rdev), minor(st.st_rdev)); - return r; - } - -#ifdef TIOCGDEV -# ifndef ENOIOCTLCMD -# define ENOIOCTLCMD 515 -# endif - if (ioctl(0, TIOCGDEV, &kdev) == 0) { - int r = findtty(res, "/dev", rlen, (dev_t)kdev); - if (0 != r) - fprintf(stderr, "bootlogd: cannot find console device " - "%d:%d under /dev\n", major(kdev), minor(kdev)); - return r; - } - if (errno != ENOIOCTLCMD) return -1; -#endif + int considx, num_consoles = 0; #ifdef __linux__ /* @@ -278,7 +259,7 @@ int consolename(char *res, int rlen) stat("/", &st); if (stat("/proc", &st2) < 0) { perror("bootlogd: /proc"); - return -1; + return 0; } if (st.st_dev == st2.st_dev) { if (mount("proc", "/proc", "proc", 0, NULL) < 0) { @@ -288,21 +269,21 @@ int consolename(char *res, int rlen) didmount = 1; } - n = 0; - r = -1; + n = -1; if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) { perror("bootlogd: /proc/cmdline"); } else { buf[0] = 0; - if ((n = read(fd, buf, sizeof(buf) - 1)) >= 0) - r = 0; - else + if ((n = read(fd, buf, sizeof(buf) - 1)) < 0) perror("bootlogd: /proc/cmdline"); close(fd); } if (didmount) umount("/proc"); + + + if (n < 0) return 0; + - if (r < 0) return r; /* * OK, so find console= in /proc/cmdline. @@ -310,21 +291,32 @@ int consolename(char *res, int rlen) */ p = buf + n; *p-- = 0; - r = -1; while (p >= buf) { if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { *p-- = 0; continue; } if (strncmp(p, "console=", 8) == 0 && - isconsole(p + 8, res, rlen)) { - r = 0; - break; + isconsole(p + 8, cons[num_consoles].name, sizeof(cons[num_consoles].name))) { + /* + * Suppress duplicates + */ + for (considx = 0; considx < num_consoles; considx++) { + if (!strcmp(cons[num_consoles].name, cons[considx].name)) { + goto dontuse; + } + } + + num_consoles++; + if (num_consoles >= max_consoles) { + break; + } } +dontuse: p--; } - if (r == 0) return r; + if (num_consoles > 0) return num_consoles; #endif /* @@ -332,12 +324,12 @@ int consolename(char *res, int rlen) * guess the default console. */ for (n = 0; defcons[n]; n++) - if (isconsole(defcons[n], res, rlen)) - return 0; + if (isconsole(defcons[n], cons[0].name, sizeof(cons[0].name))) + return 1; fprintf(stderr, "bootlogd: cannot deduce real console device\n"); - return -1; + return 0; } @@ -479,7 +471,6 @@ int main(int argc, char **argv) struct timeval tv; fd_set fds; char buf[1024]; - char realcons[1024]; char *p; char *logfile; char *pidfile; @@ -492,6 +483,9 @@ int main(int argc, char **argv) #ifndef __linux__ /* BSD-style ioctl needs an argument. */ int on = 1; #endif + int considx; + struct real_cons cons[MAX_CONSOLES]; + int num_consoles, consoles_left; fp = NULL; logfile = LOGFILE; @@ -538,6 +532,7 @@ int main(int argc, char **argv) /* * Open console device directly. */ + /* if (consolename(realcons, sizeof(realcons)) < 0) return 1; @@ -550,6 +545,25 @@ int main(int argc, char **argv) fprintf(stderr, "bootlogd: %s: %s\n", realcons, strerror(errno)); return 1; } + */ + if ((num_consoles = consolenames(cons, MAX_CONSOLES)) <= 0) + return 1; + consoles_left = num_consoles; + for (considx = 0; considx < num_consoles; considx++) { + if (strcmp(cons[considx].name, "/dev/tty0") == 0) + strcpy(cons[considx].name, "/dev/tty1"); + if (strcmp(cons[considx].name, "/dev/vc/0") == 0) + strcpy(cons[considx].name, "/dev/vc/1"); + + if ((cons[considx].fd = open_nb(cons[considx].name)) < 0) { + fprintf(stderr, "bootlogd: %s: %s\n", + cons[considx].name, strerror(errno)); + consoles_left--; + } + } + if (!consoles_left) + return 1; + /* * Grab a pty, and redirect console messages to it. @@ -633,26 +647,34 @@ int main(int argc, char **argv) if ((n = read(ptm, inptr, endptr - inptr)) >= 0) { /* * Write data (in chunks if needed) - * to the real output device. + * to the real output devices. */ - m = n; - p = inptr; - while (m > 0) { - i = write(realfd, p, m); - if (i >= 0) { - m -= i; - p += i; - continue; - } - /* - * Handle EIO (somebody hung - * up our filedescriptor) - */ - realfd = write_err(pts, realfd, - realcons, errno); - if (realfd >= 0) continue; - got_signal = 1; /* Not really */ - break; + for (considx = 0; considx < num_consoles; considx++) { + if (cons[considx].fd < 0) continue; + m = n; + p = inptr; + while (m > 0) { + i = write(cons[considx].fd, p, m); + if (i >= 0) { + m -= i; + p += i; + continue; + } + /* + * Handle EIO (somebody hung + * up our filedescriptor) + */ + cons[considx].fd = write_err(pts, + cons[considx].fd, + cons[considx].name, errno); + if (cons[considx].fd >= 0) continue; + /* + * If this was the last console, + * generate a fake signal + */ + if (--consoles_left <= 0) got_signal = 1; + break; + } } /* @@ -698,7 +720,9 @@ int main(int argc, char **argv) close(pts); close(ptm); - close(realfd); + for (considx = 0; considx < num_consoles; considx++) { + close(cons[considx].fd); + } return 0; }