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