/****************************************************************************
- * Copyright (c) 2016 Free Software Foundation, Inc. *
+ * Copyright 2019-2020,2021 Thomas E. Dickey *
+ * Copyright 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 <tty_settings.h>
#include <errno.h>
#include <stdio.h>
#endif
#if NEED_PTEM_H
-/* they neglected to define struct winsize in termios.h -- it's only
+/* they neglected to define struct winsize in termios.h -- it is only
in termio.h */
#include <sys/stream.h>
#include <sys/ptem.h>
#endif
-MODULE_ID("$Id: reset_cmd.c,v 1.9 2016/10/23 01:08:11 tom Exp $")
+MODULE_ID("$Id: reset_cmd.c,v 1.28 2021/10/02 18:08:44 tom Exp $")
/*
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
# endif
#endif
-static int my_fd;
static FILE *my_file;
-static TTY original_settings;
-static bool can_restore = FALSE;
static bool use_reset = FALSE; /* invoked as reset */
static bool use_init = FALSE; /* invoked as init */
-static void
-exit_error(void)
+static GCC_NORETURN void
+failed(const char *msg)
{
+ int code = errno;
+
+ (void) fprintf(stderr, "%s: %s: %s\n", _nc_progname, msg, strerror(code));
restore_tty_settings();
(void) fprintf(my_file, "\n");
fflush(my_file);
- ExitProgram(EXIT_FAILURE);
- /* NOTREACHED */
-}
-
-static void
-failed(const char *msg)
-{
- char temp[BUFSIZ];
-
- _nc_STRCPY(temp, _nc_progname, sizeof(temp));
- _nc_STRCAT(temp, ": ", sizeof(temp));
- _nc_STRNCAT(temp, msg, sizeof(temp), sizeof(temp) - strlen(temp) - 2);
- perror(temp);
- exit_error();
+ ExitProgram(ErrSystem(code));
/* NOTREACHED */
}
-static bool
-get_tty_settings(int fd, TTY * tty_settings)
-{
- bool success = TRUE;
- my_fd = fd;
- if (fd < 0 || GET_TTY(my_fd, tty_settings) < 0) {
- success = FALSE;
- }
- return success;
-}
-
static bool
cat_file(char *file)
{
bool sent = FALSE;
if (file != 0) {
- if ((fp = fopen(file, "r")) == 0)
+ if ((fp = safe_fopen(file, "r")) == 0)
failed(file);
while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) {
* a child program dies in raw mode.
*/
void
-reset_tty_settings(TTY * tty_settings)
+reset_tty_settings(int fd, TTY * tty_settings, int noset)
{
-#ifdef TERMIOS
- tcgetattr(my_fd, tty_settings);
-#else
- stty(my_fd, tty_settings);
-#endif
+ GET_TTY(fd, tty_settings);
#ifdef TERMIOS
#if defined(VDISCARD) && defined(CDISCARD)
);
#endif
- SET_TTY(my_fd, tty_settings);
+ if (!noset) {
+ SET_TTY(fd, tty_settings);
+ }
}
/*
int result;
if (over_strike
- && key_backspace != 0
+ && VALID_STRING(key_backspace)
&& strlen(key_backspace) == 1) {
result = key_backspace[0];
} else {
void
set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill)
{
+#if defined(EXP_WIN32_DRIVER)
+ /* noop */
+ (void) tty_settings;
+ (void) my_erase;
+ (void) my_intr;
+ (void) my_kill;
+#else
if (DISABLED(tty_settings->c_cc[VERASE]) || my_erase >= 0) {
tty_settings->c_cc[VERASE] = UChar((my_erase >= 0)
? my_erase
? my_kill
: CKILL);
}
+#endif
}
/*
void
set_conversions(TTY * tty_settings)
{
+#if defined(EXP_WIN32_DRIVER)
+ /* FIXME */
+#else
#ifdef ONLCR
tty_settings->c_oflag |= ONLCR;
#endif
#endif /* OXTABS */
/* test used to be tgetflag("NL") */
- if (newline != (char *) 0 && newline[0] == '\n' && !newline[1]) {
+ if (VALID_STRING(newline) && newline[0] == '\n' && !newline[1]) {
/* Newline, not linefeed. */
#ifdef ONLCR
tty_settings->c_oflag &= ~((unsigned) ONLCR);
}
#ifdef OXTABS
/* test used to be tgetflag("pt") */
- if (has_hardware_tabs) /* Print tabs. */
+ if (VALID_STRING(set_tab) && VALID_STRING(clear_all_tabs))
tty_settings->c_oflag &= ~OXTABS;
#endif /* OXTABS */
tty_settings->c_lflag |= (ECHOE | ECHOK);
+#endif
+}
+
+static bool
+sent_string(const char *s)
+{
+ bool sent = FALSE;
+ if (VALID_STRING(s)) {
+ tputs(s, 0, out_char);
+ sent = TRUE;
+ }
+ return sent;
+}
+
+static bool
+to_left_margin(void)
+{
+ if (VALID_STRING(carriage_return)) {
+ sent_string(carriage_return);
+ } else {
+ out_char('\r');
+ }
+ return TRUE;
}
/*
static bool
reset_tabstops(int wide)
{
- if ((init_tabs != 8) && (set_tab && clear_all_tabs)) {
+ if ((init_tabs != 8)
+ && VALID_NUMERIC(init_tabs)
+ && VALID_STRING(set_tab)
+ && VALID_STRING(clear_all_tabs)) {
int c;
- (void) putc('\r', my_file); /* Force to left margin. */
+ to_left_margin();
tputs(clear_all_tabs, 0, out_char);
-
- for (c = 8; c < wide; c += 8) {
- /* Get to the right column. In BSD tset, this used to try a bunch
- * of half-clever things with cup and hpa, for an average saving of
- * somewhat less than two character times per tab stop, less than
- * .01 sec at 2400cps. We lost all this cruft because it seemed to
- * be introducing some odd bugs.
- * -----------12345678----------- */
- (void) fputs(" ", my_file);
- tputs(set_tab, 0, out_char);
+ if (init_tabs > 1) {
+ if (init_tabs > wide)
+ init_tabs = (short) wide;
+ for (c = init_tabs; c < wide; c += init_tabs) {
+ fprintf(my_file, "%*s", init_tabs, " ");
+ tputs(set_tab, 0, out_char);
+ }
+ to_left_margin();
}
- putc('\r', my_file);
return (TRUE);
}
return (FALSE);
}
-static bool
-sent_string(const char *s)
-{
- bool sent = FALSE;
- if (s != 0) {
- tputs(s, 0, out_char);
- sent = TRUE;
- }
- return sent;
-}
-
-#define PUTCHAR(c) fputc(c, my_file)
-
/* Output startup string. */
bool
-send_init_strings(TTY * old_settings)
+send_init_strings(int fd GCC_UNUSED, TTY * old_settings)
{
int i;
bool need_flush = FALSE;
if (old_settings != 0 &&
old_settings->c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
old_settings->c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
- SET_TTY(my_fd, old_settings);
+ SET_TTY(fd, old_settings);
}
#endif
if (use_reset || use_init) {
- if (init_prog != 0) {
+ if (VALID_STRING(init_prog)) {
IGNORE_RC(system(init_prog));
}
? reset_2string
: init_2string);
- if (set_lr_margin != 0) {
- need_flush |= sent_string(TPARM_2(set_lr_margin, 0,
- columns - 1));
- } else if (set_left_margin_parm != 0
- && set_right_margin_parm != 0) {
- need_flush |= sent_string(TPARM_1(set_left_margin_parm, 0));
- need_flush |= sent_string(TPARM_1(set_right_margin_parm,
- columns - 1));
- } else if (clear_margins != 0
- && set_left_margin != 0
- && set_right_margin != 0) {
+ if (VALID_STRING(clear_margins)) {
need_flush |= sent_string(clear_margins);
- if (carriage_return != 0) {
- need_flush |= sent_string(carriage_return);
- } else {
- PUTCHAR('\r');
- }
+ } else
+#if defined(set_lr_margin)
+ if (VALID_STRING(set_lr_margin)) {
+ need_flush |= sent_string(TIPARM_2(set_lr_margin, 0, columns - 1));
+ } else
+#endif
+#if defined(set_left_margin_parm) && defined(set_right_margin_parm)
+ if (VALID_STRING(set_left_margin_parm)
+ && VALID_STRING(set_right_margin_parm)) {
+ need_flush |= sent_string(TIPARM_1(set_left_margin_parm, 0));
+ need_flush |= sent_string(TIPARM_1(set_right_margin_parm,
+ columns - 1));
+ } else
+#endif
+ if (VALID_STRING(set_left_margin)
+ && VALID_STRING(set_right_margin)) {
+ need_flush |= to_left_margin();
need_flush |= sent_string(set_left_margin);
- if (parm_right_cursor) {
- need_flush |= sent_string(TPARM_1(parm_right_cursor,
- columns - 1));
+ if (VALID_STRING(parm_right_cursor)) {
+ need_flush |= sent_string(TIPARM_1(parm_right_cursor,
+ columns - 1));
} else {
for (i = 0; i < columns - 1; i++) {
- PUTCHAR(' ');
+ out_char(' ');
+ need_flush = TRUE;
}
}
need_flush |= sent_string(set_right_margin);
- if (carriage_return != 0) {
- need_flush |= sent_string(carriage_return);
- } else {
- PUTCHAR('\r');
- }
+ need_flush |= to_left_margin();
}
need_flush |= reset_tabstops(columns);
int which,
unsigned def)
{
- unsigned older, newer;
+ unsigned older = 0, newer = 0;
char *p;
+#if defined(EXP_WIN32_DRIVER)
+ /* noop */
+ (void) old_settings;
+ (void) new_settings;
+ (void) name;
+ (void) which;
+ (void) def;
+#else
newer = new_settings->c_cc[which];
older = old_settings->c_cc[which];
if (older == newer && older == def)
return;
-
+#endif
(void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
if (DISABLED(newer)) {
void
print_tty_chars(TTY * old_settings, TTY * new_settings)
{
+#if defined(EXP_WIN32_DRIVER)
+ /* noop */
+#else
show_tty_change(old_settings, new_settings, "Erase", VERASE, CERASE);
show_tty_change(old_settings, new_settings, "Kill", VKILL, CKILL);
show_tty_change(old_settings, new_settings, "Interrupt", VINTR, CINTR);
-}
-
-/*
- * Open a file descriptor on the current terminal, to obtain its settings.
- * stderr is less likely to be redirected than stdout; try that first.
- */
-int
-save_tty_settings(TTY * tty_settings)
-{
- if (!get_tty_settings(STDERR_FILENO, tty_settings) &&
- !get_tty_settings(STDOUT_FILENO, tty_settings) &&
- !get_tty_settings(STDIN_FILENO, tty_settings) &&
- !get_tty_settings(open("/dev/tty", O_RDWR), tty_settings)) {
- failed("terminal attributes");
- }
- can_restore = TRUE;
- original_settings = *tty_settings;
- return my_fd;
-}
-
-void
-restore_tty_settings(void)
-{
- if (can_restore)
- SET_TTY(my_fd, &original_settings);
-}
-
-/* Set the modes if they've changed. */
-void
-update_tty_settings(TTY * old_settings, TTY * new_settings)
-{
- if (memcmp(new_settings, old_settings, sizeof(TTY))) {
- SET_TTY(my_fd, new_settings);
- }
+#endif
}
#if HAVE_SIZECHANGE