X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/21226fd7e6d5e69dab830cc745e2dc59ed4a00cc..b078de41dfbae96dfb831e6e06df047b669adc4c:/unix/uxplink.c diff --git a/unix/uxplink.c b/unix/uxplink.c index db881997..6d9a9b75 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -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; @@ -94,8 +107,8 @@ char *platform_default_s(const char *name) { if (!strcmp(name, "TermType")) return dupstr(getenv("TERM")); - if (!strcmp(name, "UserName")) - return get_username(); + if (!strcmp(name, "UserName")) + return get_username(); if (!strcmp(name, "SerialLine")) return dupstr("/dev/ttyS0"); return NULL; @@ -371,43 +384,44 @@ void cleanup_termios(void) bufchain stdout_data, stderr_data; -void try_output(int is_stderr) +int try_output(int is_stderr) { bufchain *chain = (is_stderr ? &stderr_data : &stdout_data); int fd = (is_stderr ? STDERR_FILENO : STDOUT_FILENO); void *senddata; - int sendlen, ret; + int sendlen, ret, fl; if (bufchain_size(chain) == 0) - return; - - bufchain_prefix(chain, &senddata, &sendlen); - ret = write(fd, senddata, sendlen); - if (ret > 0) - bufchain_consume(chain, ret); - else if (ret < 0 && errno != EWOULDBLOCK) { + return bufchain_size(&stdout_data) + bufchain_size(&stderr_data); + + fl = fcntl(fd, F_GETFL); + if (fl != -1 && !(fl & O_NONBLOCK)) + fcntl(fd, F_SETFL, fl | O_NONBLOCK); + do { + bufchain_prefix(chain, &senddata, &sendlen); + ret = write(fd, senddata, sendlen); + if (ret > 0) + bufchain_consume(chain, ret); + } while (ret == sendlen && bufchain_size(chain) != 0); + if (fl != -1 && !(fl & O_NONBLOCK)) + fcntl(fd, F_SETFL, fl); + if (ret < 0 && errno != EAGAIN) { perror(is_stderr ? "stderr: write" : "stdout: write"); exit(1); } + return bufchain_size(&stdout_data) + bufchain_size(&stderr_data); } int from_backend(void *frontend_handle, int is_stderr, const char *data, int len) { - int osize, esize; - if (is_stderr) { bufchain_add(&stderr_data, data, len); - try_output(TRUE); + return try_output(TRUE); } else { bufchain_add(&stdout_data, data, len); - try_output(FALSE); + return try_output(FALSE); } - - osize = bufchain_size(&stdout_data); - esize = bufchain_size(&stderr_data); - - return osize + esize; } int from_backend_untrusted(void *frontend_handle, const char *data, int len) @@ -582,7 +596,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. */ @@ -853,6 +869,14 @@ int main(int argc, char **argv) uxsel_init(); /* + * Unix Plink doesn't provide any way to add forwardings after the + * connection is set up, so if there are none now, we can safely set + * the "simple" flag. + */ + if (cfg.protocol == PROT_SSH && !cfg.x11_forward && !cfg.agentfwd && + cfg.portfwd[0] == '\0' && cfg.portfwd[1] == '\0') + cfg.ssh_simple = TRUE; + /* * Start up the connection. */ logctx = log_init(NULL, &cfg); @@ -883,23 +907,6 @@ int main(int argc, char **argv) local_tty = (tcgetattr(STDIN_FILENO, &orig_termios) == 0); atexit(cleanup_termios); ldisc_update(NULL, 1, 1); - - { - int fl; - /* - * Make sure that stdout/err are non-blocking. - */ - if ((fl = fcntl(STDOUT_FILENO, F_GETFL)) == -1 || - fcntl(STDOUT_FILENO, F_SETFL, fl | O_NONBLOCK) == -1) { - perror("stdout"); - exit(1); - } - if ((fl = fcntl(STDERR_FILENO, F_GETFL)) == -1 || - fcntl(STDERR_FILENO, F_SETFL, fl | O_NONBLOCK) == -1) { - perror("stderr"); - exit(1); - } - } sending = FALSE; now = GETTICKCOUNT(); @@ -1050,11 +1057,11 @@ int main(int argc, char **argv) } if (FD_ISSET(STDOUT_FILENO, &wset)) { - try_output(FALSE); + back->unthrottle(backhandle, try_output(FALSE)); } if (FD_ISSET(STDERR_FILENO, &wset)) { - try_output(TRUE); + back->unthrottle(backhandle, try_output(TRUE)); } if ((!connopen || !back->connected(backhandle)) &&