Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4:Update
sysvinit
showconsole-1.13.dif
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File showconsole-1.13.dif of Package sysvinit
--- 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" /*
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor