1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Edward Wang at The University of California, Berkeley. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)wwtty.c 3.17 (Berkeley) 08/12/90"; 13 #endif /* not lint */ 14 15 #include "ww.h" 16 #include <fcntl.h> 17 #if !defined(OLD_TTY) && !defined(TIOCGWINSZ) 18 #include <sys/ioctl.h> 19 #endif 20 21 wwgettty(d, t) 22 register struct ww_tty *t; 23 { 24 #ifdef OLD_TTY 25 if (ioctl(d, TIOCGETP, (char *)&t->ww_sgttyb) < 0) 26 goto bad; 27 if (ioctl(d, TIOCGETC, (char *)&t->ww_tchars) < 0) 28 goto bad; 29 if (ioctl(d, TIOCGLTC, (char *)&t->ww_ltchars) < 0) 30 goto bad; 31 if (ioctl(d, TIOCLGET, (char *)&t->ww_lmode) < 0) 32 goto bad; 33 if (ioctl(d, TIOCGETD, (char *)&t->ww_ldisc) < 0) 34 goto bad; 35 #else 36 if (tcgetattr(d, &t->ww_termios) < 0) 37 goto bad; 38 #endif 39 if ((t->ww_fflags = fcntl(d, F_GETFL, 0)) < 0) 40 goto bad; 41 return 0; 42 bad: 43 wwerrno = WWE_SYS; 44 return -1; 45 } 46 47 /* 48 * Set the modes of tty 'd' to 't' 49 * 'o' is the current modes. We set the line discipline only if 50 * it changes, to avoid unnecessary flushing of typeahead. 51 */ 52 wwsettty(d, t) 53 register struct ww_tty *t; 54 { 55 #ifdef OLD_TTY 56 int i; 57 58 /* XXX, for buggy tty drivers that don't wait for output to drain */ 59 while (ioctl(d, TIOCOUTQ, &i) >= 0 && i > 0) 60 usleep(100000); 61 if (ioctl(d, TIOCSETN, (char *)&t->ww_sgttyb) < 0) 62 goto bad; 63 if (ioctl(d, TIOCSETC, (char *)&t->ww_tchars) < 0) 64 goto bad; 65 if (ioctl(d, TIOCSLTC, (char *)&t->ww_ltchars) < 0) 66 goto bad; 67 if (ioctl(d, TIOCLSET, (char *)&t->ww_lmode) < 0) 68 goto bad; 69 if (ioctl(d, TIOCGETD, (char *)&i) < 0) 70 goto bad; 71 if (t->ww_ldisc != i && 72 ioctl(d, TIOCSETD, (char *)&t->ww_ldisc) < 0) 73 goto bad; 74 #else 75 #ifdef sun 76 /* XXX, for buggy tty drivers that don't wait for output to drain */ 77 (void) tcdrain(d); 78 #endif 79 if (tcsetattr(d, TCSADRAIN, &t->ww_termios) < 0) 80 goto bad; 81 #endif 82 if (fcntl(d, F_SETFL, t->ww_fflags) < 0) 83 goto bad; 84 return 0; 85 bad: 86 wwerrno = WWE_SYS; 87 return -1; 88 } 89 90 /* 91 * The ttysize and stop-start routines must also work 92 * on the control side of pseudoterminals. 93 */ 94 95 wwgetttysize(d, r, c) 96 int *r, *c; 97 { 98 struct winsize winsize; 99 100 if (ioctl(d, TIOCGWINSZ, (char *)&winsize) < 0) { 101 wwerrno = WWE_SYS; 102 return -1; 103 } 104 if (winsize.ws_row != 0) 105 *r = winsize.ws_row; 106 if (winsize.ws_col != 0) 107 *c = winsize.ws_col; 108 return 0; 109 } 110 111 wwsetttysize(d, r, c) 112 { 113 struct winsize winsize; 114 115 winsize.ws_row = r; 116 winsize.ws_col = c; 117 winsize.ws_xpixel = winsize.ws_ypixel = 0; 118 if (ioctl(d, TIOCSWINSZ, (char *)&winsize) < 0) { 119 wwerrno = WWE_SYS; 120 return -1; 121 } 122 return 0; 123 } 124 125 wwstoptty(d) 126 { 127 #if !defined(OLD_TTY) && defined(TCOOFF) 128 /* not guaranteed to work on the pty side */ 129 if (tcflow(d, TCOOFF) < 0) 130 #else 131 if (ioctl(d, TIOCSTOP, (char *)0) < 0) 132 #endif 133 { 134 wwerrno = WWE_SYS; 135 return -1; 136 } 137 return 0; 138 } 139 140 wwstarttty(d) 141 { 142 #if !defined(OLD_TTY) && defined(TCOON) 143 /* not guaranteed to work on the pty side */ 144 if (tcflow(d, TCOON) < 0) 145 #else 146 if (ioctl(d, TIOCSTART, (char *)0) < 0) 147 #endif 148 { 149 wwerrno = WWE_SYS; 150 return -1; 151 } 152 return 0; 153 } 154