X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/aef05b788c268d43559a0183d1efe9c458724b94..25d0ab1e56605c1da5e526577d8894674f063a0c:/unix/uxser.c diff --git a/unix/uxser.c b/unix/uxser.c index 85e96189..59f8aa74 100644 --- a/unix/uxser.c +++ b/unix/uxser.c @@ -2,12 +2,6 @@ * Serial back end (Unix-specific). */ -/* - * TODO: - * - * - send break. - */ - #include #include #include @@ -135,9 +129,51 @@ static const char *serial_configure(Serial serial, Config *cfg) #ifdef B115200 CHECKBAUD(115200); #endif +#ifdef B153600 + CHECKBAUD(153600); +#endif #ifdef B230400 CHECKBAUD(230400); #endif +#ifdef B307200 + CHECKBAUD(307200); +#endif +#ifdef B460800 + CHECKBAUD(460800); +#endif +#ifdef B500000 + CHECKBAUD(500000); +#endif +#ifdef B576000 + CHECKBAUD(576000); +#endif +#ifdef B921600 + CHECKBAUD(921600); +#endif +#ifdef B1000000 + CHECKBAUD(1000000); +#endif +#ifdef B1152000 + CHECKBAUD(1152000); +#endif +#ifdef B1500000 + CHECKBAUD(1500000); +#endif +#ifdef B2000000 + CHECKBAUD(2000000); +#endif +#ifdef B2500000 + CHECKBAUD(2500000); +#endif +#ifdef B3000000 + CHECKBAUD(3000000); +#endif +#ifdef B3500000 + CHECKBAUD(3500000); +#endif +#ifdef B4000000 + CHECKBAUD(4000000); +#endif #undef CHECKBAUD #undef SETBAUD cfsetispeed(&options, bflag); @@ -168,9 +204,15 @@ static const char *serial_configure(Serial serial, Config *cfg) logevent(serial->frontend, msg); sfree(msg); - options.c_cflag &= ~(IXON|IXOFF); + options.c_iflag &= ~(IXON|IXOFF); +#ifdef CRTSCTS + options.c_cflag &= ~CRTSCTS; +#endif +#ifdef CNEW_RTSCTS + options.c_cflag &= ~CNEW_RTSCTS; +#endif if (cfg->serflow == SER_FLOW_XONXOFF) { - options.c_cflag |= IXON | IXOFF; + options.c_iflag |= IXON | IXOFF; str = "XON/XOFF"; } else if (cfg->serflow == SER_FLOW_RTSCTS) { #ifdef CRTSCTS @@ -205,7 +247,25 @@ static const char *serial_configure(Serial serial, Config *cfg) options.c_cflag |= CLOCAL | CREAD; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - options.c_oflag &= ~OPOST; + options.c_iflag &= ~(ISTRIP | IGNCR | INLCR | ICRNL +#ifdef IUCLC + | IUCLC +#endif + ); + options.c_oflag &= ~(OPOST +#ifdef ONLCR + | ONLCR +#endif +#ifdef OCRNL + | OCRNL +#endif +#ifdef ONOCR + | ONOCR +#endif +#ifdef ONLRET + | ONLRET +#endif + ); options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 0; @@ -248,6 +308,8 @@ static const char *serial_init(void *frontend_handle, void **backend_handle, if (serial->fd < 0) return "Unable to open serial port"; + cloexec(serial->fd); + err = serial_configure(serial, cfg); if (err) return err; @@ -260,6 +322,11 @@ static const char *serial_init(void *frontend_handle, void **backend_handle, serial_uxsel_setup(serial); + /* + * Specials are always available. + */ + update_specials_menu(serial->frontend); + return NULL; } @@ -317,6 +384,14 @@ static int serial_select_result(int fd, int event) */ finished = TRUE; } else if (ret < 0) { +#ifdef EAGAIN + if (errno == EAGAIN) + return 1; /* spurious */ +#endif +#ifdef EWOULDBLOCK + if (errno == EWOULDBLOCK) + return 1; /* spurious */ +#endif perror("read serial port"); exit(1); } else if (ret > 0) { @@ -418,9 +493,13 @@ static void serial_size(void *handle, int width, int height) */ static void serial_special(void *handle, Telnet_Special code) { - /* - * FIXME: serial break? XON? XOFF? - */ + Serial serial = (Serial) handle; + + if (serial->fd >= 0 && code == TS_BRK) { + tcsendbreak(serial->fd, 0); + logevent(serial->frontend, "Sending serial break at user request"); + } + return; } @@ -430,10 +509,11 @@ static void serial_special(void *handle, Telnet_Special code) */ static const struct telnet_special *serial_get_specials(void *handle) { - /* - * FIXME: serial break? XON? XOFF? - */ - return NULL; + static const struct telnet_special specials[] = { + {"Break", TS_BRK}, + {NULL, TS_EXITMENU} + }; + return specials; } static int serial_connected(void *handle) @@ -506,5 +586,7 @@ Backend serial_backend = { serial_provide_logctx, serial_unthrottle, serial_cfg_info, - 1 + "serial", + PROT_SERIAL, + 0 };