1 /* $NetBSD: wwtty.c,v 1.7 2003/08/07 11:17:46 agc Exp $ */ 2 3 /* 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Edward Wang at The University of California, Berkeley. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)wwtty.c 8.1 (Berkeley) 6/6/93"; 39 #else 40 __RCSID("$NetBSD: wwtty.c,v 1.7 2003/08/07 11:17:46 agc Exp $"); 41 #endif 42 #endif /* not lint */ 43 44 #include <sys/types.h> 45 #if !defined(OLD_TTY) && !defined(TIOCGWINSZ) 46 #include <sys/ioctl.h> 47 #endif 48 #include <fcntl.h> 49 #include "ww.h" 50 51 int 52 wwgettty(int d, struct ww_tty *t) 53 { 54 #ifdef OLD_TTY 55 if (ioctl(d, TIOCGETP, (char *)&t->ww_sgttyb) < 0) 56 goto bad; 57 if (ioctl(d, TIOCGETC, (char *)&t->ww_tchars) < 0) 58 goto bad; 59 if (ioctl(d, TIOCGLTC, (char *)&t->ww_ltchars) < 0) 60 goto bad; 61 if (ioctl(d, TIOCLGET, (char *)&t->ww_lmode) < 0) 62 goto bad; 63 if (ioctl(d, TIOCGETD, (char *)&t->ww_ldisc) < 0) 64 goto bad; 65 #else 66 if (tcgetattr(d, &t->ww_termios) < 0) 67 goto bad; 68 #endif 69 return 0; 70 bad: 71 wwerrno = WWE_SYS; 72 return -1; 73 } 74 75 /* 76 * Set the modes of tty 'd' to 't' 77 * 'o' is the current modes. We set the line discipline only if 78 * it changes, to avoid unnecessary flushing of typeahead. 79 */ 80 int 81 wwsettty(int d, struct ww_tty *t) 82 { 83 #ifdef OLD_TTY 84 int i; 85 86 /* XXX, for buggy tty drivers that don't wait for output to drain */ 87 while (ioctl(d, TIOCOUTQ, &i) >= 0 && i > 0) 88 usleep(100000); 89 if (ioctl(d, TIOCSETN, (char *)&t->ww_sgttyb) < 0) 90 goto bad; 91 if (ioctl(d, TIOCSETC, (char *)&t->ww_tchars) < 0) 92 goto bad; 93 if (ioctl(d, TIOCSLTC, (char *)&t->ww_ltchars) < 0) 94 goto bad; 95 if (ioctl(d, TIOCLSET, (char *)&t->ww_lmode) < 0) 96 goto bad; 97 if (ioctl(d, TIOCGETD, (char *)&i) < 0) 98 goto bad; 99 if (t->ww_ldisc != i && 100 ioctl(d, TIOCSETD, (char *)&t->ww_ldisc) < 0) 101 goto bad; 102 #else 103 #ifdef sun 104 /* XXX, for buggy tty drivers that don't wait for output to drain */ 105 (void) tcdrain(d); 106 #endif 107 if (tcsetattr(d, TCSADRAIN, &t->ww_termios) < 0) 108 goto bad; 109 #endif 110 return 0; 111 bad: 112 wwerrno = WWE_SYS; 113 return -1; 114 } 115 116 /* 117 * The ttysize and stop-start routines must also work 118 * on the control side of pseudoterminals. 119 */ 120 121 int 122 wwgetttysize(int d, int *r, int *c) 123 { 124 struct winsize winsize; 125 126 if (ioctl(d, TIOCGWINSZ, (char *)&winsize) < 0) { 127 wwerrno = WWE_SYS; 128 return -1; 129 } 130 if (winsize.ws_row != 0) 131 *r = winsize.ws_row; 132 if (winsize.ws_col != 0) 133 *c = winsize.ws_col; 134 return 0; 135 } 136 137 int 138 wwsetttysize(int d, int r, int c) 139 { 140 struct winsize winsize; 141 142 winsize.ws_row = r; 143 winsize.ws_col = c; 144 winsize.ws_xpixel = winsize.ws_ypixel = 0; 145 if (ioctl(d, TIOCSWINSZ, (char *)&winsize) < 0) { 146 wwerrno = WWE_SYS; 147 return -1; 148 } 149 return 0; 150 } 151 152 int 153 wwstoptty(int d) 154 { 155 #if !defined(OLD_TTY) && defined(TCOOFF) 156 /* not guaranteed to work on the pty side */ 157 if (tcflow(d, TCOOFF) < 0) 158 #else 159 if (ioctl(d, TIOCSTOP, (char *)0) < 0) 160 #endif 161 { 162 wwerrno = WWE_SYS; 163 return -1; 164 } 165 return 0; 166 } 167 168 int 169 wwstarttty(int d) 170 { 171 #if !defined(OLD_TTY) && defined(TCOON) 172 /* not guaranteed to work on the pty side */ 173 if (tcflow(d, TCOON) < 0) 174 #else 175 if (ioctl(d, TIOCSTART, (char *)0) < 0) 176 #endif 177 { 178 wwerrno = WWE_SYS; 179 return -1; 180 } 181 return 0; 182 } 183