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