]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - progs/tset.c
ncurses 6.0 - patch 20160730
[ncurses.git] / progs / tset.c
index 21203e3de07468618ababe2e4d1f38ef961d1a18..8417effc039e2ef724731cef849f9669c61f6ce8 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2015,2016 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -119,7 +119,7 @@ char *ttyname(int fd);
 #include <dump_entry.h>
 #include <transform.h>
 
-MODULE_ID("$Id: tset.c,v 1.92 2013/10/12 22:17:20 tom Exp $")
+MODULE_ID("$Id: tset.c,v 1.100 2016/07/30 21:32:26 tom Exp $")
 
 /*
  * SCO defines TIOCGSIZE and the corresponding struct.  Other systems (SunOS,
@@ -154,6 +154,7 @@ static void err(const char *,...) GCC_NORETURN;
 
 const char *_nc_progname = "tset";
 
+static int my_fd;
 static TTY mode, oldmode, original;
 
 static bool opt_c;             /* set control-chars */
@@ -187,7 +188,7 @@ static void
 exit_error(void)
 {
     if (can_restore)
-       SET_TTY(STDERR_FILENO, &original);
+       SET_TTY(my_fd, &original);
     (void) fprintf(stderr, "\n");
     fflush(stderr);
     ExitProgram(EXIT_FAILURE);
@@ -223,6 +224,17 @@ failed(const char *msg)
     /* NOTREACHED */
 }
 
+static bool
+get_mode(int fd)
+{
+    bool success = TRUE;
+    my_fd = fd;
+    if (GET_TTY(my_fd, &mode) < 0) {
+       success = FALSE;
+    }
+    return success;
+}
+
 static void
 cat(char *file)
 {
@@ -307,87 +319,89 @@ typedef struct map {
 
 static MAP *cur, *maplist;
 
+#define DATA(name,value) { { name }, value }
+
 typedef struct speeds {
-    const char *string;
+    const char string[7];
     int speed;
 } SPEEDS;
 
 static const SPEEDS speeds[] =
 {
-    {"0", B0},
-    {"50", B50},
-    {"75", B75},
-    {"110", B110},
-    {"134", B134},
-    {"134.5", B134},
-    {"150", B150},
-    {"200", B200},
-    {"300", B300},
-    {"600", B600},
-    {"1200", B1200},
-    {"1800", B1800},
-    {"2400", B2400},
-    {"4800", B4800},
-    {"9600", B9600},
+    DATA("0", B0),
+    DATA("50", B50),
+    DATA("75", B75),
+    DATA("110", B110),
+    DATA("134", B134),
+    DATA("134.5", B134),
+    DATA("150", B150),
+    DATA("200", B200),
+    DATA("300", B300),
+    DATA("600", B600),
+    DATA("1200", B1200),
+    DATA("1800", B1800),
+    DATA("2400", B2400),
+    DATA("4800", B4800),
+    DATA("9600", B9600),
     /* sgttyb may define up to this point */
 #ifdef B19200
-    {"19200", B19200},
+    DATA("19200", B19200),
 #endif
 #ifdef B38400
-    {"38400", B38400},
+    DATA("38400", B38400),
 #endif
 #ifdef B19200
-    {"19200", B19200},
+    DATA("19200", B19200),
 #endif
 #ifdef B38400
-    {"38400", B38400},
+    DATA("38400", B38400),
 #endif
 #ifdef B19200
-    {"19200", B19200},
+    DATA("19200", B19200),
 #else
 #ifdef EXTA
-    {"19200", EXTA},
+    DATA("19200", EXTA),
 #endif
 #endif
 #ifdef B38400
-    {"38400", B38400},
+    DATA("38400", B38400),
 #else
 #ifdef EXTB
-    {"38400", EXTB},
+    DATA("38400", EXTB),
 #endif
 #endif
 #ifdef B57600
-    {"57600", B57600},
+    DATA("57600", B57600),
 #endif
 #ifdef B115200
-    {"115200", B115200},
+    DATA("115200", B115200),
 #endif
 #ifdef B230400
-    {"230400", B230400},
+    DATA("230400", B230400),
 #endif
 #ifdef B460800
-    {"460800", B460800},
+    DATA("460800", B460800),
 #endif
-    {(char *) 0, 0}
 };
+#undef DATA
 
 static int
 tbaudrate(char *rate)
 {
-    const SPEEDS *sp;
-    int found = FALSE;
+    const SPEEDS *sp = 0;
+    size_t n;
 
     /* The baudrate number can be preceded by a 'B', which is ignored. */
     if (*rate == 'B')
        ++rate;
 
-    for (sp = speeds; sp->string; ++sp) {
-       if (!CaselessCmp(rate, sp->string)) {
-           found = TRUE;
+    for (n = 0; n < SIZEOF(speeds); ++n) {
+       if (!CaselessCmp(rate, speeds[n].string)) {
+           sp = speeds + n;
            break;
        }
     }
-    if (!found)
+    if (sp == 0)
        err("unknown baud rate %s", rate);
     return (sp->speed);
 }
@@ -587,7 +601,7 @@ get_termcap_entry(char *userarg)
     if ((ttype = getenv("TERM")) != 0)
        goto map;
 
-    if ((ttypath = ttyname(STDERR_FILENO)) != 0) {
+    if ((ttypath = ttyname(my_fd)) != 0) {
        p = _nc_basename(ttypath);
 #if HAVE_GETTTYNAM
        /*
@@ -635,13 +649,14 @@ get_termcap_entry(char *userarg)
      * real entry from /etc/termcap.  This prevents us from being fooled
      * by out of date stuff in the environment.
      */
-  found:if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) {
+  found:
+    if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) {
        /* 'unsetenv("TERMCAP")' is not portable.
         * The 'environ' array is better.
         */
        int n;
        for (n = 0; environ[n] != 0; n++) {
-           if (!strncmp("TERMCAP=", environ[n], 8)) {
+           if (!strncmp("TERMCAP=", environ[n], (size_t) 8)) {
                while ((environ[n] = environ[n + 1]) != 0) {
                    n++;
                }
@@ -744,7 +759,7 @@ get_termcap_entry(char *userarg)
 #define DISABLED(val)   ((int)(val) <= 0)
 #endif
 
-#define CHK(val, dft)   (DISABLED(val) ? dft : val)
+#define CHK(val, dft)   (unsigned char) (DISABLED(val) ? dft : val)
 
 static bool set_tabs(void);
 
@@ -756,9 +771,9 @@ static void
 reset_mode(void)
 {
 #ifdef TERMIOS
-    tcgetattr(STDERR_FILENO, &mode);
+    tcgetattr(my_fd, &mode);
 #else
-    stty(STDERR_FILENO, &mode);
+    stty(my_fd, &mode);
 #endif
 
 #ifdef TERMIOS
@@ -876,7 +891,7 @@ reset_mode(void)
        );
 #endif
 
-    SET_TTY(STDERR_FILENO, &mode);
+    SET_TTY(my_fd, &mode);
 }
 
 /*
@@ -1015,7 +1030,7 @@ set_init(void)
 #ifdef TAB3
     if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
        oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
-       SET_TTY(STDERR_FILENO, &oldmode);
+       SET_TTY(my_fd, &oldmode);
     }
 #endif
     settle = set_tabs();
@@ -1166,26 +1181,26 @@ obsolete(char **argv)
 static void
 usage(void)
 {
-    static const char *tbl[] =
+#define DATA(s) s "\n"
+    static const char msg[] =
     {
-       ""
-       ,"Options:"
-       ,"  -c          set control characters"
-       ,"  -e ch       erase character"
-       ,"  -I          no initialization strings"
-       ,"  -i ch       interrupt character"
-       ,"  -k ch       kill character"
-       ,"  -m mapping  map identifier to type"
-       ,"  -Q          do not output control key settings"
-       ,"  -r          display term on stderr"
-       ,"  -s          output TERM set command"
-       ,"  -V          print curses-version"
-       ,"  -w          set window-size"
+       DATA("")
+       DATA("Options:")
+       DATA("  -c          set control characters")
+       DATA("  -e ch       erase character")
+       DATA("  -I          no initialization strings")
+       DATA("  -i ch       interrupt character")
+       DATA("  -k ch       kill character")
+       DATA("  -m mapping  map identifier to type")
+       DATA("  -Q          do not output control key settings")
+       DATA("  -r          display term on stderr")
+       DATA("  -s          output TERM set command")
+       DATA("  -V          print curses-version")
+       DATA("  -w          set window-size")
     };
-    unsigned n;
+#undef DATA
     (void) fprintf(stderr, "Usage: %s [options] [terminal]\n", _nc_progname);
-    for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n)
-       fprintf(stderr, "%s\n", tbl[n]);
+    fputs(msg, stderr);
     exit_error();
     /* NOTREACHED */
 }
@@ -1205,9 +1220,10 @@ main(int argc, char **argv)
     const char *p;
     const char *ttype;
 
+    my_fd = STDERR_FILENO;
     obsolete(argv);
     noinit = noset = quiet = Sflag = sflag = showterm = 0;
-    while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:np:qQSrsVw")) != -1) {
+    while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQSrsVw")) != -1) {
        switch (ch) {
        case 'c':               /* set control-chars */
            opt_c = TRUE;
@@ -1233,8 +1249,6 @@ main(int argc, char **argv)
        case 'm':               /* map identifier to type */
            add_mapping(0, optarg);
            break;
-       case 'n':               /* OBSOLETE: set new tty driver */
-           break;
        case 'p':               /* OBSOLETE: map identifier to type */
            add_mapping("plugboard", optarg);
            break;
@@ -1275,8 +1289,15 @@ main(int argc, char **argv)
     if (!opt_c && !opt_w)
        opt_c = opt_w = TRUE;
 
-    if (GET_TTY(STDERR_FILENO, &mode) < 0)
-       failed("standard error");
+    /*
+     * stderr is less likely to be redirected than stdout; try that first.
+     */
+    if (!get_mode(STDERR_FILENO) &&
+       !get_mode(STDOUT_FILENO) &&
+       !get_mode(STDIN_FILENO) &&
+       !get_mode(open("/dev/tty", O_RDWR))) {
+       failed("terminal attributes");
+    }
     can_restore = TRUE;
     original = oldmode = mode;
 #ifdef TERMIOS
@@ -1290,7 +1311,7 @@ main(int argc, char **argv)
        reset_mode();
     }
 
-    (void) get_termcap_entry(*argv);
+    ttype = get_termcap_entry(*argv);
 
     if (!noset) {
 #if HAVE_SIZECHANGE
@@ -1300,13 +1321,13 @@ main(int argc, char **argv)
        if (opt_w) {
            STRUCT_WINSIZE win;
            /* Set window size if not set already */
-           (void) ioctl(STDERR_FILENO, IOCTL_GET_WINSIZE, &win);
+           (void) ioctl(my_fd, IOCTL_GET_WINSIZE, &win);
            if (WINSIZE_ROWS(win) == 0 &&
                WINSIZE_COLS(win) == 0 &&
                tlines > 0 && tcolumns > 0) {
-               WINSIZE_ROWS(win) = tlines;
-               WINSIZE_COLS(win) = tcolumns;
-               (void) ioctl(STDERR_FILENO, IOCTL_SET_WINSIZE, &win);
+               WINSIZE_ROWS(win) = (unsigned short) tlines;
+               WINSIZE_COLS(win) = (unsigned short) tcolumns;
+               (void) ioctl(my_fd, IOCTL_SET_WINSIZE, &win);
            }
        }
 #endif
@@ -1319,14 +1340,11 @@ main(int argc, char **argv)
 
            /* Set the modes if they've changed. */
            if (memcmp(&mode, &oldmode, sizeof(mode))) {
-               SET_TTY(STDERR_FILENO, &mode);
+               SET_TTY(my_fd, &mode);
            }
        }
     }
 
-    /* Get the terminal name from the entry. */
-    ttype = _nc_first_name(cur_term->type.term_names);
-
     if (noset)
        (void) printf("%s\n", ttype);
     else {