X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/848d09e66dbb11beb59d93cefd1b82a234b35d24..42af6a672d16302ee1b8971a7cc164120f7572ab:/unix/uxplink.c diff --git a/unix/uxplink.c b/unix/uxplink.c index 13369b10..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) { + 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); @@ -1033,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)) &&