mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
Add support for resetting the terminal modes on stderr to something sensible
before printing error messages to it. This should fix the stair-stepping in Plink's progress messages. [originally from svn r7745]
This commit is contained in:
parent
38ee5fc58d
commit
faa6e26d38
18
unix/unix.h
18
unix/unix.h
@ -60,6 +60,18 @@ extern long tickcount_offset;
|
||||
#define WCHAR wchar_t
|
||||
#define BYTE unsigned char
|
||||
|
||||
/*
|
||||
* Unix-specific global flag
|
||||
*
|
||||
* FLAG_STDERR_TTY indicates that standard error might be a terminal and
|
||||
* might get its configuration munged, so anything trying to output plain
|
||||
* text (i.e. with newlines in it) will need to put it back into cooked
|
||||
* mode first. Applications setting this flag should also call
|
||||
* stderr_tty_init() before messing with any terminal modes, and can call
|
||||
* premsg() before outputting text to stderr and postmsg() afterwards.
|
||||
*/
|
||||
#define FLAG_STDERR_TTY 0x1000
|
||||
|
||||
/* Things pty.c needs from pterm.c */
|
||||
char *get_x_display(void *frontend);
|
||||
int font_dimension(void *frontend, int which);/* 0 for width, 1 for height */
|
||||
@ -91,6 +103,12 @@ char *x_get_default(const char *key);
|
||||
/* Things uxstore.c provides to pterm.c */
|
||||
void provide_xrm_string(char *string);
|
||||
|
||||
/* Things provided by uxcons.c */
|
||||
struct termios;
|
||||
void stderr_tty_init(void);
|
||||
void premsg(struct termios *);
|
||||
void postmsg(struct termios *);
|
||||
|
||||
/* The interface used by uxsel.c */
|
||||
void uxsel_init(void);
|
||||
typedef int (*uxsel_callback_fn)(int fd, int event);
|
||||
|
@ -18,6 +18,31 @@ int console_batch_mode = FALSE;
|
||||
|
||||
static void *console_logctx = NULL;
|
||||
|
||||
static struct termios orig_termios_stderr;
|
||||
static int stderr_is_a_tty;
|
||||
|
||||
void stderr_tty_init()
|
||||
{
|
||||
/* Ensure that if stderr is a tty, we can get it back to a sane state. */
|
||||
if ((flags & FLAG_STDERR_TTY) && isatty(STDERR_FILENO)) {
|
||||
stderr_is_a_tty = TRUE;
|
||||
tcgetattr(STDERR_FILENO, &orig_termios_stderr);
|
||||
}
|
||||
}
|
||||
|
||||
void premsg(struct termios *cf)
|
||||
{
|
||||
if (stderr_is_a_tty) {
|
||||
tcgetattr(STDERR_FILENO, cf);
|
||||
tcsetattr(STDERR_FILENO, TCSADRAIN, &orig_termios_stderr);
|
||||
}
|
||||
}
|
||||
void postmsg(struct termios *cf)
|
||||
{
|
||||
if (stderr_is_a_tty)
|
||||
tcsetattr(STDERR_FILENO, TCSADRAIN, cf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up and exit.
|
||||
*/
|
||||
@ -101,6 +126,7 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
|
||||
static const char abandoned[] = "Connection abandoned.\n";
|
||||
|
||||
char line[32];
|
||||
struct termios cf;
|
||||
|
||||
/*
|
||||
* Verify the key.
|
||||
@ -110,6 +136,7 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
|
||||
if (ret == 0) /* success - key matched OK */
|
||||
return 1;
|
||||
|
||||
premsg(&cf);
|
||||
if (ret == 2) { /* key was different */
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, wrongmsg_batch, keytype, fingerprint);
|
||||
@ -141,9 +168,11 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
|
||||
if (line[0] != '\0' && line[0] != '\r' && line[0] != '\n') {
|
||||
if (line[0] == 'y' || line[0] == 'Y')
|
||||
store_host_key(host, port, keytype, keystr);
|
||||
postmsg(&cf);
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -166,7 +195,9 @@ int askalg(void *frontend, const char *algtype, const char *algname,
|
||||
static const char abandoned[] = "Connection abandoned.\n";
|
||||
|
||||
char line[32];
|
||||
struct termios cf;
|
||||
|
||||
premsg(&cf);
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, msg_batch, algtype, algname);
|
||||
return 0;
|
||||
@ -187,9 +218,11 @@ int askalg(void *frontend, const char *algtype, const char *algname,
|
||||
}
|
||||
|
||||
if (line[0] == 'y' || line[0] == 'Y') {
|
||||
postmsg(&cf);
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -215,7 +248,9 @@ int askappend(void *frontend, Filename filename,
|
||||
"Logging will not be enabled.\n";
|
||||
|
||||
char line[32];
|
||||
struct termios cf;
|
||||
|
||||
premsg(&cf);
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path);
|
||||
fflush(stderr);
|
||||
@ -235,6 +270,7 @@ int askappend(void *frontend, Filename filename,
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
}
|
||||
|
||||
postmsg(&cf);
|
||||
if (line[0] == 'y' || line[0] == 'Y')
|
||||
return 2;
|
||||
else if (line[0] == 'n' || line[0] == 'N')
|
||||
@ -266,7 +302,10 @@ void old_keyfile_warning(void)
|
||||
"Once the key is loaded into PuTTYgen, you can perform\n"
|
||||
"this conversion simply by saving it again.\n";
|
||||
|
||||
struct termios cf;
|
||||
premsg(&cf);
|
||||
fputs(message, stderr);
|
||||
postmsg(&cf);
|
||||
}
|
||||
|
||||
void console_provide_logctx(void *logctx)
|
||||
@ -276,8 +315,11 @@ void console_provide_logctx(void *logctx)
|
||||
|
||||
void logevent(void *frontend, const char *string)
|
||||
{
|
||||
struct termios cf;
|
||||
premsg(&cf);
|
||||
if (console_logctx)
|
||||
log_eventlog(console_logctx, string);
|
||||
postmsg(&cf);
|
||||
}
|
||||
|
||||
static void console_data_untrusted(const char *data, int len)
|
||||
|
@ -27,14 +27,19 @@
|
||||
|
||||
void *logctx;
|
||||
|
||||
static struct termios orig_termios;
|
||||
|
||||
void fatalbox(char *p, ...)
|
||||
{
|
||||
struct termios cf;
|
||||
va_list ap;
|
||||
premsg(&cf);
|
||||
fprintf(stderr, "FATAL ERROR: ");
|
||||
va_start(ap, p);
|
||||
vfprintf(stderr, p, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
postmsg(&cf);
|
||||
if (logctx) {
|
||||
log_free(logctx);
|
||||
logctx = NULL;
|
||||
@ -43,12 +48,15 @@ void fatalbox(char *p, ...)
|
||||
}
|
||||
void modalfatalbox(char *p, ...)
|
||||
{
|
||||
struct termios cf;
|
||||
va_list ap;
|
||||
premsg(&cf);
|
||||
fprintf(stderr, "FATAL ERROR: ");
|
||||
va_start(ap, p);
|
||||
vfprintf(stderr, p, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
postmsg(&cf);
|
||||
if (logctx) {
|
||||
log_free(logctx);
|
||||
logctx = NULL;
|
||||
@ -57,12 +65,15 @@ void modalfatalbox(char *p, ...)
|
||||
}
|
||||
void connection_fatal(void *frontend, char *p, ...)
|
||||
{
|
||||
struct termios cf;
|
||||
va_list ap;
|
||||
premsg(&cf);
|
||||
fprintf(stderr, "FATAL ERROR: ");
|
||||
va_start(ap, p);
|
||||
vfprintf(stderr, p, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
postmsg(&cf);
|
||||
if (logctx) {
|
||||
log_free(logctx);
|
||||
logctx = NULL;
|
||||
@ -71,17 +82,19 @@ void connection_fatal(void *frontend, char *p, ...)
|
||||
}
|
||||
void cmdline_error(char *p, ...)
|
||||
{
|
||||
struct termios cf;
|
||||
va_list ap;
|
||||
premsg(&cf);
|
||||
fprintf(stderr, "plink: ");
|
||||
va_start(ap, p);
|
||||
vfprintf(stderr, p, ap);
|
||||
va_end(ap);
|
||||
fputc('\n', stderr);
|
||||
postmsg(&cf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int local_tty = FALSE; /* do we have a local tty? */
|
||||
static struct termios orig_termios;
|
||||
|
||||
static Backend *back;
|
||||
static void *backhandle;
|
||||
@ -582,7 +595,9 @@ int main(int argc, char **argv)
|
||||
default_protocol = PROT_SSH;
|
||||
default_port = 22;
|
||||
|
||||
flags = FLAG_STDERR;
|
||||
flags = FLAG_STDERR | FLAG_STDERR_TTY;
|
||||
|
||||
stderr_tty_init();
|
||||
/*
|
||||
* Process the command line.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user