X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ftty.c;h=1765878c27c977f56aa6feb5258c30b832887878;hb=3331b39c48edb228a82580253c4ffffd1f3775bf;hp=adee8bfac653de5ad94183dbb02caf998b8cea69;hpb=4691b05226b475c3b678bbed49f16c2398921ba7;p=sympathy.git diff --git a/src/tty.c b/src/tty.c index adee8bf..1765878 100644 --- a/src/tty.c +++ b/src/tty.c @@ -1,5 +1,5 @@ /* - * testtty.c: + * tty.c: * * Copyright (c) 2008 James McKenzie , * All rights reserved. @@ -10,206 +10,327 @@ static char rcsid[] = "$Id$"; /* * $Log$ - * Revision 1.1 2008/02/07 01:02:52 james + * Revision 1.11 2008/02/20 18:31:53 james * *** empty log message *** * - * Revision 1.3 2008/02/06 17:53:28 james + * Revision 1.10 2008/02/15 23:52:12 james * *** empty log message *** * - * Revision 1.2 2008/02/04 02:05:06 james + * Revision 1.9 2008/02/15 03:32:07 james * *** empty log message *** * - * Revision 1.1 2008/02/04 01:32:39 james + * Revision 1.8 2008/02/14 10:36:18 james + * *** empty log message *** + * + * Revision 1.7 2008/02/14 10:34:30 james + * *** empty log message *** + * + * Revision 1.6 2008/02/13 16:59:34 james + * *** empty log message *** + * + * Revision 1.5 2008/02/13 16:57:29 james + * *** empty log message *** + * + * Revision 1.4 2008/02/12 22:36:46 james + * *** empty log message *** + * + * Revision 1.3 2008/02/09 15:47:28 james * *** empty log message *** * */ + #include "project.h" -static void -set_nonblocking (int fd) +static int +speed_t_to_baud (speed_t s) { - long arg; - arg = fcntl (fd, F_GETFL, arg); - arg |= O_NONBLOCK; - fcntl (fd, F_SETFL, arg); -} + switch (s) + { +#ifdef B0 + case B0: + return 0; +#endif +#ifdef B50 + case B50: + return 50; +#endif +#ifdef B75 + case B75: + return 75; +#endif +#ifdef B110 + case B110: + return 110; +#endif +#ifdef B134 + case B134: + return 134; +#endif +#ifdef B150 + case B150: + return 150; +#endif +#ifdef B200 + case B200: + return 200; +#endif +#ifdef B300 + case B300: + return 300; +#endif +#ifdef B600 + case B600: + return 600; +#endif +#ifdef B1200 + case B1200: + return 1200; +#endif +#ifdef B1800 + case B1800: + return 1800; +#endif +#ifdef B2400 + case B2400: + return 2400; +#endif +#ifdef B4800 + case B4800: + return 4800; +#endif +#ifdef B9600 + case B9600: + return 9600; +#endif +#ifdef B19200 + case B19200: + return 19200; +#endif +#ifdef B38400 + case B38400: + return 38400; +#endif +#ifdef B57600 + case B57600: + return 57600; +#endif +#ifdef B115200 + case B115200: + return 115200; +#endif +#ifdef B230400 + case B230400: + return 230400; +#endif + } -static void -set_blocking (int fd) -{ - long arg; - arg = fcntl (fd, F_GETFL, arg); - arg &= ~O_NONBLOCK; - fcntl (fd, F_SETFL, arg); + return -1; } -static void -default_termios (struct termios *termios) +static speed_t +baud_to_speed_t (int baud) { - - memset (termios, 0, sizeof (termios)); - - termios->c_iflag = ICRNL | IXON; - termios->c_oflag = OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0; - termios->c_lflag = - ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE; - - termios->c_cc[VINTR] = 003; - termios->c_cc[VQUIT] = 034; - termios->c_cc[VERASE] = 0177; - termios->c_cc[VKILL] = 025; - termios->c_cc[VEOF] = 004; - termios->c_cc[VEOL] = 0; - termios->c_cc[VEOL2] = 0; - termios->c_cc[VSTART] = 021; - termios->c_cc[VSTOP] = 023; - termios->c_cc[VSUSP] = 032; - termios->c_cc[VLNEXT] = 026; - termios->c_cc[VWERASE] = 027; - termios->c_cc[VREPRINT] = 022; - termios->c_cc[VDISCARD] = 017; - - termios->c_cflag = CS8 | CREAD | CLOCAL; - - cfsetispeed (termios, B9600); - cfsetospeed (termios, B9600); + switch (baud) + { +#ifdef B0 + case 0: + return B0; +#endif +#ifdef B50 + case 50: + return B50; +#endif +#ifdef B75 + case 75: + return B75; +#endif +#ifdef B110 + case 110: + return B110; +#endif +#ifdef B134 + case 134: + return B134; +#endif +#ifdef B150 + case 150: + return B150; +#endif +#ifdef B200 + case 200: + return B200; +#endif +#ifdef B300 + case 300: + return B300; +#endif +#ifdef B600 + case 600: + return B600; +#endif +#ifdef B1200 + case 1200: + return B1200; +#endif +#ifdef B1800 + case 1800: + return B1800; +#endif +#ifdef B2400 + case 2400: + return B2400; +#endif +#ifdef B4800 + case 4800: + return B4800; +#endif +#ifdef B9600 + case 9600: + return B9600; +#endif +#ifdef B19200 + case 19200: + return B19200; +#endif +#ifdef B38400 + case 38400: + return B38400; +#endif +#ifdef B57600 + case 57600: + return B57600; +#endif +#ifdef B115200 + case 115200: + return B115200; +#endif +#ifdef B230400 + case 230400: + return B230400; +#endif + } + return -1; } - -static int -open_fd_to_bash (void) /*thump */ +void +tty_pre_select (TTY * t, fd_set * rfds, fd_set * wfds) { - pid_t child; - int fd; - struct winsize winsize = { 0 }; - struct termios termios; - - default_termios (&termios); + int line; + struct timeval now, dif; - winsize.ws_row = VT102_ROWS; - winsize.ws_col = VT102_COLS; + if (t->hanging_up) + { - child = forkpty (&fd, NULL, &termios, &winsize); + gettimeofday (&now, NULL); + timersub (&now, &t->hangup_clock, &dif); + if (dif.tv_sec) + { +#if 0 + fprintf (stderr, "+DTR\n"); +#endif - switch (child) - { - case -1: /*boo hiss */ - return -1; - case 0: /*waaah */ - setenv ("TERM", "vt102", 1); - execl ("/bin/sh", "-", (char *) 0); - _exit (-1); + line = TIOCM_DTR; + ioctl (t->rfd, TIOCMBIS, &line); + t->hanging_up = 0; + } } - return fd; -} + FD_SET (t->rfd, rfds); +} -TTY * -tty_new_test (void) +int +tty_get_status (TTY * t, TTY_Status * s) { - TTY *t; - t = (TTY *) malloc (sizeof (TTY)); - t->fd = open_fd_to_bash (); - set_nonblocking (t->fd); + s->lines = 0; + ioctl (t->rfd, TIOCMGET, &s->lines); - return t; -} - -static int -wrap_read (int fd, void *buf, int len) -{ - int red; +#if 0 + if (t->hanging_up) + fprintf (stderr, "s->lines & TIOCM_DTR=%x\n", s->lines & TIOCM_DTR); +#endif - red = read (fd, buf, len); - if (!red) + if (tcgetattr (t->rfd, &s->termios)) return -1; - if ((red < 0) && (errno == EAGAIN)) - red = 0; + s->baud = speed_t_to_baud (cfgetispeed (&s->termios)); + s->blocked = t->blocked; - return red; + return 0; } -static int -wrap_write (int fd, void *buf, int len) +void +tty_set_baud (TTY * t, int rate) { - int writ; + struct termios tios = { 0 }; - writ = write (fd, buf, len); - if (!writ) - return -1; + speed_t s = baud_to_speed_t (rate); + + if (s == (speed_t) - 1) + return; - if ((writ < 0) && (errno == -EAGAIN)) - writ = 0; + if (tcgetattr (t->rfd, &tios)) + return; - return writ; + cfsetispeed (&tios, s); + cfsetospeed (&tios, s); + + tcsetattr (t->rfd, TCSANOW, &tios); } -int -tty_read (TTY * t, void *buf, int len) +void +tty_send_break (TTY * t) { - int red, done = 0; - + tcsendbreak (t->wfd, 0); +} - do - { +void +tty_set_flow (TTY * t, int flow) +{ + struct termios tios = { 0 }; - red = wrap_read (t->fd, buf, len); - if (red < 0) - return -1; - if (!red) - return done; + if (tcgetattr (t->rfd, &tios)) + return; - buf += red; - len -= red; - done += red; - } - while (len); + if (flow) + tios.c_cflag |= CRTSCTS; + else + tios.c_cflag &= ~CRTSCTS; + tcsetattr (t->rfd, TCSANOW, &tios); - return done; } - -int -tty_write (TTY * t, void *buf, int len) +void +tty_hangup (TTY * t) { - int writ, done = 0; + int line; + line = TIOCM_DTR; + ioctl (t->rfd, TIOCMBIC, &line); + + t->hanging_up = 1; + gettimeofday (&t->hangup_clock, NULL); #if 0 - { - int i; - uint8_t *p = buf; - for (i = 0; i < len; ++i) - fprintf (stderr, "vw: %03o %c\n", p[i], p[i] > 31 ? p[i] : 32); - } + fprintf (stderr, "-DTR\n"); #endif - do - { - - writ = wrap_write (t->fd, buf, len); - if (writ < 0) - return -1; - if (!writ) - sleep (1); +} - buf += writ; - len -= writ; - done += writ; - } - while (len); +#if 0 +int +tty_post_select (Context * c, fd_set * rfds, fd_set * wfds) +{ - return done; + if (FD_ISSET (c->t->rfd, rfds)) + { + if (vt102_dispatch (&c)) + return -1; + } + return 0; } -void -tty_free (TTY * t) -{ - close (t->fd); - free (t); -} +#endif