]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - progs/tset.c
ncurses 6.4 - patch 20240414
[ncurses.git] / progs / tset.c
index 7a0f521ec2b1304bf75ec77900cdc910556cd5be..8bc502a36967b7afeabe4709ca3641b893262106 100644 (file)
@@ -1,5 +1,6 @@
 /****************************************************************************
- * Copyright (c) 1998-2015,2016 Free Software Foundation, Inc.              *
+ * Copyright 2020-2021,2024 Thomas E. Dickey                                *
+ * Copyright 1998-2016,2017 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            *
 #include <reset_cmd.h>
 #include <termcap.h>
 #include <transform.h>
+#include <tty_settings.h>
 
-#if HAVE_GETTTYNAM && HAVE_TTYENT_H
+#if HAVE_GETTTYNAM
 #include <ttyent.h>
 #endif
 #ifdef NeXT
 char *ttyname(int fd);
 #endif
 
-MODULE_ID("$Id: tset.c,v 1.108 2016/08/20 23:53:44 tom Exp $")
+MODULE_ID("$Id: tset.c,v 1.134 2024/04/13 18:59:53 tom Exp $")
 
 #ifndef environ
 extern char **environ;
@@ -106,6 +108,8 @@ const char *_nc_progname = "tset";
 
 #define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
 
+static GCC_NORETURN void exit_error(void);
+
 static int
 CaselessCmp(const char *a, const char *b)
 {                              /* strcasecmp isn't portable */
@@ -118,7 +122,7 @@ CaselessCmp(const char *a, const char *b)
     return LOWERCASE(*a) - LOWERCASE(*b);
 }
 
-static void
+static GCC_NORETURN void
 exit_error(void)
 {
     restore_tty_settings();
@@ -128,8 +132,8 @@ exit_error(void)
     /* NOTREACHED */
 }
 
-static void
-err(const char *fmt,...)
+static GCC_NORETURN void
+err(const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
@@ -140,7 +144,7 @@ err(const char *fmt,...)
     /* NOTREACHED */
 }
 
-static void
+static GCC_NORETURN void
 failed(const char *msg)
 {
     char temp[BUFSIZ];
@@ -152,7 +156,8 @@ failed(const char *msg)
     } else {
        _nc_STRCPY(temp, "tset: ", sizeof(temp));
     }
-    perror(strncat(temp, msg, sizeof(temp) - strlen(temp) - 2));
+    _nc_STRNCAT(temp, msg, sizeof(temp), sizeof(temp) - strlen(temp) - 2);
+    perror(temp);
     exit_error();
     /* NOTREACHED */
 }
@@ -162,7 +167,6 @@ static const char *
 askuser(const char *dflt)
 {
     static char answer[256];
-    char *p;
 
     /* We can get recalled; if so, don't continue uselessly. */
     clearerr(stdin);
@@ -171,7 +175,10 @@ askuser(const char *dflt)
        exit_error();
        /* NOTREACHED */
     }
+
     for (;;) {
+       char *p;
+
        if (dflt)
            (void) fprintf(stderr, "Terminal type? [%s] ", dflt);
        else
@@ -222,10 +229,16 @@ static MAP *cur, *maplist;
 #define DATA(name,value) { { name }, value }
 
 typedef struct speeds {
-    const char string[7];
+    const char string[8];
     int speed;
 } SPEEDS;
 
+#if defined(EXP_WIN32_DRIVER)
+static const SPEEDS speeds[] =
+{
+    {"0", 0}
+};
+#else
 static const SPEEDS speeds[] =
 {
     DATA("0", B0),
@@ -273,17 +286,60 @@ static const SPEEDS speeds[] =
 #ifdef B57600
     DATA("57600", B57600),
 #endif
+#ifdef B76800
+    DATA("76800", B57600),
+#endif
 #ifdef B115200
     DATA("115200", B115200),
 #endif
+#ifdef B153600
+    DATA("153600", B153600),
+#endif
 #ifdef B230400
     DATA("230400", B230400),
 #endif
+#ifdef B307200
+    DATA("307200", B307200),
+#endif
 #ifdef B460800
     DATA("460800", B460800),
 #endif
+#ifdef B500000
+    DATA("500000", B500000),
+#endif
+#ifdef B576000
+    DATA("576000", B576000),
+#endif
+#ifdef B921600
+    DATA("921600", B921600),
+#endif
+#ifdef B1000000
+    DATA("1000000", B1000000),
+#endif
+#ifdef B1152000
+    DATA("1152000", B1152000),
+#endif
+#ifdef B1500000
+    DATA("1500000", B1500000),
+#endif
+#ifdef B2000000
+    DATA("2000000", B2000000),
+#endif
+#ifdef B2500000
+    DATA("2500000", B2500000),
+#endif
+#ifdef B3000000
+    DATA("3000000", B3000000),
+#endif
+#ifdef B3500000
+    DATA("3500000", B3500000),
+#endif
+#ifdef B4000000
+    DATA("4000000", B4000000),
+#endif
 };
 #undef DATA
+#endif
 
 static int
 tbaudrate(char *rate)
@@ -296,6 +352,10 @@ tbaudrate(char *rate)
        ++rate;
 
     for (n = 0; n < SIZEOF(speeds); ++n) {
+       if (n > 0 && (speeds[n].speed <= speeds[n - 1].speed)) {
+           /* if the speeds are not increasing, likely a numeric overflow */
+           break;
+       }
        if (!CaselessCmp(rate, speeds[n].string)) {
            sp = speeds + n;
            break;
@@ -485,12 +545,14 @@ get_termcap_entry(int fd, char *userarg)
     int errret;
     char *p;
     const char *ttype;
+#if HAVE_PATH_TTYS
 #if HAVE_GETTTYNAM
     struct ttyent *t;
 #else
     FILE *fp;
 #endif
     char *ttypath;
+#endif /* HAVE_PATH_TTYS */
 
     (void) fd;
 
@@ -503,6 +565,7 @@ get_termcap_entry(int fd, char *userarg)
     if ((ttype = getenv("TERM")) != 0)
        goto map;
 
+#if HAVE_PATH_TTYS
     if ((ttypath = ttyname(fd)) != 0) {
        p = _nc_basename(ttypath);
 #if HAVE_GETTTYNAM
@@ -540,6 +603,7 @@ get_termcap_entry(int fd, char *userarg)
        }
 #endif /* HAVE_GETTTYNAM */
     }
+#endif /* HAVE_PATH_TTYS */
 
     /* If still undefined, use "unknown". */
     ttype = "unknown";
@@ -578,7 +642,7 @@ get_termcap_entry(int fd, char *userarg)
            ttype = askuser(0);
     }
     /* Find the terminfo entry.  If it doesn't exist, ask the user. */
-    while (setupterm((NCURSES_CONST char *) ttype, STDOUT_FILENO, &errret)
+    while (setupterm((NCURSES_CONST char *) ttype, fd, &errret)
           != OK) {
        if (errret == 0) {
            (void) fprintf(stderr, "%s: unknown terminal type %s\n",
@@ -661,27 +725,36 @@ print_shell_commands(const char *ttype)
 static void
 usage(void)
 {
-#define DATA(s) s "\n"
+#define SKIP(s)                        /* nothing */
+#define KEEP(s) s "\n"
     static const char msg[] =
     {
-       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")
+       KEEP("")
+       KEEP("Options:")
+       SKIP("  -a arpanet  (obsolete)")
+       KEEP("  -c          set control characters")
+       SKIP("  -d dialup   (obsolete)")
+       KEEP("  -e ch       erase character")
+       KEEP("  -I          no initialization strings")
+       KEEP("  -i ch       interrupt character")
+       KEEP("  -k ch       kill character")
+       KEEP("  -m mapping  map identifier to type")
+       SKIP("  -p plugboard (obsolete)")
+       KEEP("  -Q          do not output control key settings")
+       KEEP("  -q          display term only, do no changes")
+       KEEP("  -r          display term on stderr")
+       SKIP("  -S          (obsolete)")
+       KEEP("  -s          output TERM set command")
+       KEEP("  -V          print curses-version")
+       KEEP("  -w          set window-size")
+       KEEP("")
+       KEEP("If neither -c/-w are given, both are assumed.")
     };
-#undef DATA
+#undef KEEP
+#undef SKIP
     (void) fprintf(stderr, "Usage: %s [options] [terminal]\n", _nc_progname);
     fputs(msg, stderr);
-    exit_error();
+    ExitProgram(EXIT_FAILURE);
     /* NOTREACHED */
 }
 
@@ -701,15 +774,15 @@ main(int argc, char **argv)
     int terasechar = -1;       /* new erase character */
     int intrchar = -1;         /* new interrupt character */
     int tkillchar = -1;                /* new kill character */
-    int my_fd = -1;
+    int my_fd;
     bool opt_c = FALSE;                /* set control-chars */
     bool opt_w = FALSE;                /* set window-size */
     TTY mode, oldmode;
 
-    my_fd = STDERR_FILENO;
+    _nc_progname = _nc_rootname(*argv);
     obsolete(argv);
     noinit = noset = quiet = Sflag = sflag = showterm = 0;
-    while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQSrsVw")) != -1) {
+    while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:p:qQrSsVw")) != -1) {
        switch (ch) {
        case 'c':               /* set control-chars */
            opt_c = TRUE;
@@ -765,7 +838,6 @@ main(int argc, char **argv)
        }
     }
 
-    _nc_progname = _nc_rootname(*argv);
     argc -= optind;
     argv += optind;
 
@@ -775,19 +847,21 @@ main(int argc, char **argv)
     if (!opt_c && !opt_w)
        opt_c = opt_w = TRUE;
 
-    my_fd = save_tty_settings(&mode);
+    my_fd = save_tty_settings(&mode, TRUE);
     oldmode = mode;
 #ifdef TERMIOS
     ospeed = (NCURSES_OSPEED) cfgetospeed(&mode);
+#elif defined(EXP_WIN32_DRIVER)
+    ospeed = 0;
 #else
     ospeed = (NCURSES_OSPEED) mode.sg_ospeed;
 #endif
 
     if (same_program(_nc_progname, PROG_RESET)) {
        reset_start(stderr, TRUE, FALSE);
-       reset_tty_settings(&mode);
+       reset_tty_settings(my_fd, &mode, noset);
     } else {
-       reset_start(stderr, FALSE, FALSE);
+       reset_start(stderr, FALSE, TRUE);
     }
 
     ttype = get_termcap_entry(my_fd, *argv);
@@ -795,7 +869,7 @@ main(int argc, char **argv)
     if (!noset) {
 #if HAVE_SIZECHANGE
        if (opt_w) {
-           set_window_size(my_fd, lines, columns);
+           set_window_size(my_fd, &lines, &columns);
        }
 #endif
        if (opt_c) {
@@ -803,10 +877,14 @@ main(int argc, char **argv)
            set_conversions(&mode);
 
            if (!noinit) {
-               if (send_init_strings(&oldmode)) {
+               if (send_init_strings(my_fd, &oldmode)) {
+                   const char *name;
+
                    (void) putc('\r', stderr);
                    (void) fflush(stderr);
-                   (void) napms(1000);         /* Settle the terminal. */
+                   if (IsRealTty(my_fd, name)) {
+                       (void) napms(1000);     /* Settle the terminal. */
+                   }
                }
            }