[PATCH 09/16] Move serial console handling code out into its own file.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
 loader/Makefile.am |    2 +-
 loader/init.c      |  208 +------------------------------------------------
 loader/loader.c    |    5 +
 loader/serial.c    |  220 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 loader/serial.h    |    9 ++
 5 files changed, 237 insertions(+), 207 deletions(-)
 create mode 100644 loader/serial.c
 create mode 100644 loader/serial.h

diff --git a/loader/Makefile.am b/loader/Makefile.am
index 02ab6cf..243817c 100644
--- a/loader/Makefile.am
+++ b/loader/Makefile.am
@@ -50,7 +50,7 @@ loader_SOURCES     = loader.c copy.c moduleinfo.c loadermisc.c \
                      getparts.c dirbrowser.c fwloader.c ibft.c hardware.c \
                      method.c cdinstall.c hdinstall.c nfsinstall.c \
                      urlinstall.c net.c urls.c rpmextract.c readvars.c \
-                     unpack.c
+                     serial.c unpack.c
 
 dirbrowser_CFLAGS  = $(COMMON_CFLAGS) -DSTANDALONE
 dirbrowser_LDADD   = $(NEWT_LIBS)
diff --git a/loader/init.c b/loader/init.c
index 429eada..d4f9c0d 100644
--- a/loader/init.c
+++ b/loader/init.c
@@ -83,71 +83,6 @@ static void fatal_error(int usePerror) {
 #endif
 }
 
-static int setupTerminal(int fd) {
-    struct winsize winsize;
-    gpointer value = NULL;
-
-    if (ioctl(fd, TIOCGWINSZ, &winsize)) {
-        printf("failed to get winsize");
-        fatal_error(1);
-    }
-
-    winsize.ws_row = 24;
-    winsize.ws_col = 80;
-
-    if (ioctl(fd, TIOCSWINSZ, &winsize)) {
-        printf("failed to set winsize");
-        fatal_error(1);
-    }
-
-    if (!strcmp(ttyname(fd), "/dev/hvc0")) {
-        /* using an HMC on a POWER system, use vt320 */
-        env[ENV_TERM] = "TERM=vt320";
-    } else {
-        /* use the no-advanced-video vt100 definition */
-        env[ENV_TERM] = "TERM=vt100-nav";
-
-        /* unless the user specifies that they want utf8 */
-        if (g_hash_table_lookup_extended(cmdline, "utf8", NULL, &value)) {
-            env[ENV_TERM] = "TERM=vt100";
-        }
-    }
-
-    return 0;
-}
-#if defined(__sparc__)
-static int termcmp(struct termios *a, struct termios *b) {
-    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
-    a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag)
-    return 1;
-    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
-}
-#endif
-
-#if !defined(__s390__) && !defined(__s390x__) && !defined(__sparc__)
-static int termcmp(struct termios *a, struct termios *b) {
-    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
-        a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag ||
-        a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
-        return 1;
-    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
-}
-#endif
-
-static void termReset(void) {
-    /* change to tty1 */
-    ioctl(0, VT_ACTIVATE, 1);
-    /* reset terminal */
-    tcsetattr(0, TCSANOW, &ts);
-    /* Shift in, default color, move down 100 lines */
-    /* ^O        ^[[0m          ^[[100E */
-    printf("\017\033[0m\033[100E\n");
-}
-
-static void copyErrorFn (char *msg) {
-    printf(msg);
-}
-
 static char *setupMallocPerturb(char *value)
 {
     FILE *f;
@@ -211,7 +146,6 @@ static void setupEnv(void)
 int main(int argc, char **argv) {
     pid_t installpid;
     int waitStatus;
-    int fd = -1;
     int doShutdown =0;
     reboot_action shutdown_method = HALT;
     int isSerial = 0;
@@ -220,9 +154,7 @@ int main(int argc, char **argv) {
     int doKill = 1;
     char * argvc[15];
     char ** argvp = argvc;
-    char twelve = 12;
-    struct serial_struct si;
-    int i, disable_keys;
+    int i;
     int ret;
     gpointer value = NULL;
 
@@ -239,14 +171,6 @@ int main(int argc, char **argv) {
 
     printf("anaconda installer init version %s starting\n", VERSION);
 
-    /* these args are only for testing from commandline */
-    for (i = 1; i < argc; i++) {
-        if (!strcmp (argv[i], "serial")) {
-            isSerial = 1;
-            break;
-        }
-    }
-
     /* if anaconda dies suddenly we are doomed, so at least make a coredump */
     struct rlimit corelimit = { RLIM_INFINITY,  RLIM_INFINITY};
     ret = setrlimit(RLIMIT_CORE, &corelimit);
@@ -254,130 +178,6 @@ int main(int argc, char **argv) {
         perror("setrlimit failed - no coredumps will be available");
     }
 
-#if !defined(__s390__) && !defined(__s390x__)
-    static struct termios orig_cmode;
-    static int            orig_flags;
-    struct termios cmode, mode;
-    int cfd;
-    
-    cfd =  open("/dev/console", O_RDONLY);
-    tcgetattr(cfd,&orig_cmode);
-    orig_flags = fcntl(cfd, F_GETFL);
-    close(cfd);
-
-    cmode = orig_cmode;
-    cmode.c_lflag &= (~ECHO);
-
-    cfd = open("/dev/console", O_WRONLY);
-    tcsetattr(cfd,TCSANOW,&cmode);
-    close(cfd);
-
-    /* handle weird consoles */
-#if defined(__powerpc__)
-    char * consoles[] = { "/dev/hvc0", /* hvc for JS20 */
-
-                          "/dev/hvsi0", "/dev/hvsi1",
-                          "/dev/hvsi2", /* hvsi for POWER5 */
-                          NULL };
-#elif defined (__ia64__)
-    char * consoles[] = { "/dev/ttySG0", "/dev/xvc0", "/dev/hvc0", NULL };
-#elif defined (__i386__) || defined (__x86_64__)
-    char * consoles[] = { "/dev/xvc0", "/dev/hvc0", NULL };
-#else
-    char * consoles[] = { NULL };
-#endif
-    for (i = 0; consoles[i] != NULL; i++) {
-        if ((fd = open(consoles[i], O_RDWR)) >= 0 && !tcgetattr(fd, &mode) && !termcmp(&cmode, &mode)) {
-            printf("anaconda installer init version %s using %s as console\n",
-                   VERSION, consoles[i]);
-            isSerial = 3;
-            console = strdup(consoles[i]);
-            break;
-        }
-        close(fd);
-    }
-
-    cfd = open("/dev/console", O_WRONLY);
-    tcsetattr(cfd,TCSANOW,&orig_cmode);
-    close(cfd); 
-
-    if ((fd < 0) && (ioctl (0, TIOCLINUX, &twelve) < 0)) {
-        isSerial = 2;
-
-        if (ioctl(0, TIOCGSERIAL, &si) == -1) {
-            isSerial = 0;
-        }
-    }
-
-    if (isSerial && (isSerial != 3)) {
-        char *device = "/dev/ttyS0";
-
-        printf("anaconda installer init version %s using a serial console\n", 
-               VERSION);
-
-        if (isSerial == 2)
-            device = "/dev/console";
-        fd = open(device, O_RDWR, 0);
-        if (fd < 0)
-            device = "/dev/tts/0";
-
-        if (fd < 0) {
-            printf("failed to open %s\n", device);
-            fatal_error(1);
-        }
-
-        setupTerminal(fd);
-    } else if (isSerial == 3) {
-        setupTerminal(fd);
-    } else if (fd < 0)  {
-        fd = open("/dev/tty1", O_RDWR, 0);
-        if (fd < 0)
-            fd = open("/dev/vc/1", O_RDWR, 0);
-
-        if (fd < 0) {
-            printf("failed to open /dev/tty1 and /dev/vc/1");
-            fatal_error(1);
-        }
-    }
-
-    setsid();
-    if (ioctl(0, TIOCSCTTY, NULL)) {
-        printf("could not set new controlling tty\n");
-    }
-
-    dup2(fd, 0);
-    dup2(fd, 1);
-    dup2(fd, 2);
-    if (fd > 2)
-        close(fd);
-#else
-    dup2(0, 1);
-    dup2(0, 2);
-#endif
-
-    /* disable Ctrl+Z, Ctrl+C, etc ... but not in rescue mode */
-    disable_keys = 1;
-    if (argc > 1)
-        if (strstr(argv[1], "rescue"))
-            disable_keys = 0;
-
-    if (disable_keys) {
-        tcgetattr(0, &ts);
-        ts.c_iflag &= ~BRKINT;
-        ts.c_iflag |= IGNBRK;
-        ts.c_iflag &= ~ISIG;
-        tcsetattr(0, TCSANOW, &ts);
-    }
-
-
-    /* Go into normal init mode - keep going, and then do a orderly shutdown
-       when:
-
-       1) /bin/install exits
-       2) we receive a SIGHUP 
-    */
-
-    printf("running install...\n"); 
 
     if (!(installpid = fork())) {
         /* child */
@@ -407,11 +207,7 @@ int main(int argc, char **argv) {
     if (!WIFEXITED(waitStatus) ||
         (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus))) {
 
-        /* Restore terminal */
-        cfd =  open("/dev/console", O_RDONLY);
-        tcsetattr(cfd, TCSANOW, &orig_cmode);
-        fcntl(cfd, F_SETFL, orig_flags);
-        close(cfd);
+        restore_console(&orig_cmode, orig_flags);
 
         shutdown_method = DELAYED_REBOOT;
         printf("install exited abnormally [%d/%d] ", WIFEXITED(waitStatus),
diff --git a/loader/loader.c b/loader/loader.c
index 5043994..db5445b 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -61,6 +61,7 @@
 #include <mcheck.h>
 #endif
 
+#include "serial.h"
 #include "copy.h"
 #include "getparts.h"
 #include "loader.h"
@@ -1892,6 +1893,8 @@ int main(int argc, char ** argv) {
     char * outputKSFile = NULL;
 
     struct loaderData_s loaderData;
+    struct termios orig_cmode;
+    int orig_flags;
 
     char *path, *fmt;
     GSList *dd, *dditer;
@@ -1969,6 +1972,8 @@ int main(int argc, char ** argv) {
 
     logMessage(INFO, "anaconda version %s on %s starting", VERSION, getProductArch());
 
+    init_serial(&orig_cmode, &orig_flags, cmdline);
+
     if ((FL_SERIAL(flags) || FL_VIRTPCONSOLE(flags)) && 
         !hasGraphicalOverride()) {
         logMessage(INFO, "text mode forced due to serial/virtpconsole");
diff --git a/loader/serial.c b/loader/serial.c
new file mode 100644
index 0000000..2e9fa5b
--- /dev/null
+++ b/loader/serial.c
@@ -0,0 +1,220 @@
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <linux/serial.h>
+
+#include <sys/ioctl.h>
+
+#include <glib.h>
+
+#include "../pyanaconda/isys/log.h"
+
+#if defined(__sparc__)
+static int termcmp(struct termios *a, struct termios *b) {
+    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
+    a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag)
+    return 1;
+    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
+}
+#endif
+
+#if !defined(__s390__) && !defined(__s390x__) && !defined(__sparc__)
+static int termcmp(struct termios *a, struct termios *b) {
+    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
+        a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag ||
+        a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
+        return 1;
+    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
+}
+#endif
+
+void get_mode_and_flags(struct termios *cmode, int *flags) {
+    int fd;
+
+    fd = open("/dev/console", O_RDONLY);
+    tcgetattr(fd, cmode);
+    *flags = fcntl(fd, F_GETFL);
+    close(fd);
+}
+
+void set_mode(struct termios *cmode) {
+    int fd;
+
+    fd = open("/dev/console", O_WRONLY);
+    tcsetattr(fd, TCSANOW, cmode);
+    close(fd);
+}
+
+void restore_mode(struct termios *orig_cmode) {
+    int fd;
+
+    fd = open("/dev/console", O_WRONLY);
+    tcsetattr(fd, TCSANOW, orig_cmode);
+    close(fd);
+}
+
+void restore_flags(int orig_flags) {
+    int fd;
+
+    fd = open("/dev/console", O_WRONLY);
+    fcntl(fd, F_SETFL, orig_flags);
+    close(fd);
+}
+
+static int serial_requested(GHashTable *cmdline) {
+    if (cmdline && g_hash_table_lookup_extended(cmdline, "serial", NULL, NULL))
+        return 1;
+    else
+        return 0;
+}
+
+static int get_serial_fd() {
+    int i, fd = -1;
+    int weird = 0;
+    char twelve = 12;
+    char *console = NULL;
+    static struct serial_struct si;
+
+    struct termios orig_cmode, cmode, mode;
+    int orig_flags;
+
+    get_mode_and_flags(&orig_cmode, &orig_flags);
+
+    cmode = orig_cmode;
+    cmode.c_lflag &= (~ECHO);
+
+    set_mode(&cmode);
+
+    /* handle weird consoles */
+#if defined(__powerpc__)
+    char * consoles[] = { "/dev/hvc0", /* hvc for JS20 */
+
+                          "/dev/hvsi0", "/dev/hvsi1",
+                          "/dev/hvsi2", /* hvsi for POWER5 */
+                          NULL };
+#elif defined (__i386__) || defined (__x86_64__)
+    char * consoles[] = { "/dev/xvc0", "/dev/hvc0", NULL };
+#else
+    char * consoles[] = { NULL };
+#endif
+    for (i = 0; consoles[i] != NULL; i++) {
+        if ((fd = open(consoles[i], O_RDWR)) >= 0 && !tcgetattr(fd, &mode) && !termcmp(&cmode, &mode)) {
+            console = strdup(consoles[i]);
+            logMessage(INFO, "set console to %s at %d", console, __LINE__);
+            weird = 1;
+            break;
+        }
+        close(fd);
+    }
+
+    restore_mode(&orig_cmode);
+
+    if (fd < 0 && ioctl(0, TIOCLINUX, &twelve) < 0) {
+        console = "/dev/console";
+
+        if (ioctl(0, TIOCGSERIAL, &si) == -1)
+            console = NULL;
+    }
+    else
+        console = "/dev/ttyS0";
+
+    if (console && !weird) {
+        fd = open(console, O_RDWR, 0);
+        if (fd < 0)
+            console = "/dev/tts/0";
+
+        if (fd < 0) {
+            logMessage(ERROR, "failed to open %s", console);
+            return -1;
+        }
+    }
+
+    return fd;
+}
+
+static void set_term(int fd, GHashTable *cmdline) {
+    if (!strcmp(ttyname(fd), "/dev/hvc0")) {
+        /* using an HMC on a POWER system, use vt320 */
+        setenv("TERM", "vt320", 1);
+    } else {
+        if (cmdline && g_hash_table_lookup_extended(cmdline, "utf8", NULL, NULL))
+            setenv("TERM", "vt100", 1);
+        else
+            /* use the no-advanced-video vt100 definition */
+            setenv("TERM", "vt100-nav", 1);
+    }
+}
+
+void init_serial(struct termios *orig_cmode, int *orig_flags, GHashTable *cmdline) {
+#if !defined(__s390__) && !defined(__s390x__)
+    int fd;
+
+    /* We need to get the original mode and flags here (in addition to inside
+     * get_serial) so we'll have them for later when we restore the console
+     * prior to rebooting.
+     */
+    get_mode_and_flags(orig_cmode, orig_flags);
+
+    if (!serial_requested(cmdline) || (fd = get_serial_fd()) == -1) {
+        /* This is not a serial console install. */
+        if ((fd = open("/dev/tty1", O_RDWR, 0)) < 0) {
+            if ((fd = open("/dev/vc/1", O_RDWR, 0)) < 0) {
+                fprintf(stderr, "failed to open /dev/tty1 and /dev/vc/1");
+                exit(1);
+            }
+        }
+    }
+    else {
+        struct winsize winsize;
+
+        if (ioctl(fd, TIOCGWINSZ, &winsize)) {
+            logMessage(ERROR, "failed to get window size");
+            exit(1);
+        }
+
+        winsize.ws_row = 24;
+        winsize.ws_col = 80;
+
+        if (ioctl(fd, TIOCSWINSZ, &winsize)) {
+            logMessage(ERROR, "failed to set window size");
+            exit(1);
+        }
+
+        set_term(fd, cmdline);
+    }
+
+    setsid();
+    if (ioctl(0, TIOCSCTTY, NULL))
+        fprintf(stderr, "could not set new controlling tty\n");
+
+    if (dup2(fd, 0) == -1)
+       logMessage(ERROR, "dup2(%d): %m", __LINE__);
+
+    if (dup2(fd, 1) == -1)
+       logMessage(ERROR, "dup2(%d): %m", __LINE__);
+
+    if (dup2(fd, 2) == -1)
+       logMessage(ERROR, "dup2(%d): %m", __LINE__);
+
+    if (fd > 2)
+        close(fd);
+#else
+    dup2(0, 1);
+    dup2(0, 2);
+#endif
+
+    /* disable Ctrl+Z, Ctrl+C, etc ... but not in rescue mode */
+    if (cmdline && !g_hash_table_lookup_extended(cmdline, "rescue", NULL, NULL)) {
+        struct termios ts;
+
+        tcgetattr(0, &ts);
+        ts.c_iflag &= ~BRKINT;
+        ts.c_iflag |= IGNBRK;
+        ts.c_iflag &= ~ISIG;
+        tcsetattr(0, TCSANOW, &ts);
+    }
+}
diff --git a/loader/serial.h b/loader/serial.h
new file mode 100644
index 0000000..82e086c
--- /dev/null
+++ b/loader/serial.h
@@ -0,0 +1,9 @@
+#include <termios.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+void get_mode_and_flags(struct termios *cmode, int *flags);
+void set_mode(struct termios *cmode);
+void restore_console(struct termios *orig_cmode, int orig_flags);
+void init_serial(struct termios *orig_cmode, int *orig_flags, GHashTable *cmdline);
-- 
1.7.4.1

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux