1 /**************************************************************************** 2 * Copyright 2020 Thomas E. Dickey * 3 * Copyright 1998-2016,2017 Free Software Foundation, Inc. * 4 * * 5 * Permission is hereby granted, free of charge, to any person obtaining a * 6 * copy of this software and associated documentation files (the * 7 * "Software"), to deal in the Software without restriction, including * 8 * without limitation the rights to use, copy, modify, merge, publish, * 9 * distribute, distribute with modifications, sublicense, and/or sell * 10 * copies of the Software, and to permit persons to whom the Software is * 11 * furnished to do so, subject to the following conditions: * 12 * * 13 * The above copyright notice and this permission notice shall be included * 14 * in all copies or substantial portions of the Software. * 15 * * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 23 * * 24 * Except as contained in this notice, the name(s) of the above copyright * 25 * holders shall not be used in advertising or otherwise to promote the * 26 * sale, use or other dealings in this Software without prior written * 27 * authorization. * 28 ****************************************************************************/ 29 30 /**************************************************************************** 31 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 32 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 33 * and: Thomas E. Dickey 1996-on * 34 ****************************************************************************/ 35 36 /* 37 * lib_baudrate.c 38 * 39 */ 40 41 #include <curses.priv.h> 42 #include <termcap.h> /* ospeed */ 43 #if defined(__FreeBSD__) || defined(__OpenBSD__) 44 #include <sys/param.h> 45 #endif 46 47 /* 48 * These systems use similar header files, which define B1200 as 1200, etc., 49 * but can be overridden by defining USE_OLD_TTY so B1200 is 9, which makes all 50 * of the indices up to B115200 fit nicely in a 'short', allowing us to retain 51 * ospeed's type for compatibility. 52 */ 53 #if NCURSES_OSPEED_COMPAT && \ 54 ((defined(__FreeBSD__) && (__FreeBSD_version < 700000)) || \ 55 defined(__NetBSD__) || \ 56 ((defined(__OpenBSD__) && OpenBSD < 201510)) || \ 57 defined(__APPLE__)) 58 #undef B0 59 #undef B50 60 #undef B75 61 #undef B110 62 #undef B134 63 #undef B150 64 #undef B200 65 #undef B300 66 #undef B600 67 #undef B1200 68 #undef B1800 69 #undef B2400 70 #undef B4800 71 #undef B9600 72 #undef B19200 73 #undef EXTA 74 #undef B38400 75 #undef EXTB 76 #undef B57600 77 #undef B115200 78 #undef B230400 79 #undef B460800 80 #undef B921600 81 #define USE_OLD_TTY 82 #include <sys/ttydev.h> 83 #else 84 #undef USE_OLD_TTY 85 #endif /* USE_OLD_TTY */ 86 87 MODULE_ID("$Id: lib_baudrate.c,v 1.45 2020/09/05 21:15:32 tom Exp $") 88 89 /* 90 * int 91 * baudrate() 92 * 93 * Returns the current terminal's baud rate. 94 * 95 */ 96 97 struct speed { 98 int given_speed; /* values for 'ospeed' */ 99 int actual_speed; /* the actual speed */ 100 }; 101 102 #if !defined(EXP_WIN32_DRIVER) 103 #define DATA(number) { B##number, number } 104 105 static struct speed const speeds[] = 106 { 107 DATA(0), 108 DATA(50), 109 DATA(75), 110 DATA(110), 111 DATA(134), 112 DATA(150), 113 DATA(200), 114 DATA(300), 115 DATA(600), 116 DATA(1200), 117 DATA(1800), 118 DATA(2400), 119 DATA(4800), 120 DATA(9600), 121 #ifdef B19200 122 DATA(19200), 123 #elif defined(EXTA) 124 {EXTA, 19200}, 125 #endif 126 #ifdef B28800 127 DATA(28800), 128 #endif 129 #ifdef B38400 130 DATA(38400), 131 #elif defined(EXTB) 132 {EXTB, 38400}, 133 #endif 134 #ifdef B57600 135 DATA(57600), 136 #endif 137 /* ifdef to prevent overflow when OLD_TTY is not available */ 138 #if !(NCURSES_OSPEED_COMPAT && defined(__FreeBSD__) && (__FreeBSD_version > 700000)) 139 #ifdef B76800 140 DATA(76800), 141 #endif 142 #ifdef B115200 143 DATA(115200), 144 #endif 145 #ifdef B153600 146 DATA(153600), 147 #endif 148 #ifdef B230400 149 DATA(230400), 150 #endif 151 #ifdef B307200 152 DATA(307200), 153 #endif 154 #ifdef B460800 155 DATA(460800), 156 #endif 157 #ifdef B500000 158 DATA(500000), 159 #endif 160 #ifdef B576000 161 DATA(576000), 162 #endif 163 #ifdef B921600 164 DATA(921600), 165 #endif 166 #ifdef B1000000 167 DATA(1000000), 168 #endif 169 #ifdef B1152000 170 DATA(1152000), 171 #endif 172 #ifdef B1500000 173 DATA(1500000), 174 #endif 175 #ifdef B2000000 176 DATA(2000000), 177 #endif 178 #ifdef B2500000 179 DATA(2500000), 180 #endif 181 #ifdef B3000000 182 DATA(3000000), 183 #endif 184 #ifdef B3500000 185 DATA(3500000), 186 #endif 187 #ifdef B4000000 188 DATA(4000000), 189 #endif 190 #endif 191 }; 192 #endif /* !EXP_WIN32_DRIVER */ 193 194 NCURSES_EXPORT(int) 195 _nc_baudrate(int OSpeed) 196 { 197 #if defined(EXP_WIN32_DRIVER) 198 /* On Windows this is a noop */ 199 (void) OSpeed; 200 return (OK); 201 #else 202 #if !USE_REENTRANT 203 static int last_OSpeed; 204 static int last_baudrate; 205 #endif 206 207 int result = ERR; 208 209 if (OSpeed < 0) 210 OSpeed = (NCURSES_OSPEED) OSpeed; 211 if (OSpeed < 0) 212 OSpeed = (unsigned short) OSpeed; 213 #if !USE_REENTRANT 214 if (OSpeed == last_OSpeed) { 215 result = last_baudrate; 216 } 217 #endif 218 if (result == ERR) { 219 if (OSpeed >= 0) { 220 unsigned i; 221 222 for (i = 0; i < SIZEOF(speeds); i++) { 223 if (speeds[i].given_speed > OSpeed) { 224 break; 225 } 226 if (speeds[i].given_speed == OSpeed) { 227 result = speeds[i].actual_speed; 228 break; 229 } 230 } 231 } 232 #if !USE_REENTRANT 233 if (OSpeed != last_OSpeed) { 234 last_OSpeed = OSpeed; 235 last_baudrate = result; 236 } 237 #endif 238 } 239 return (result); 240 #endif /* !EXP_WIN32_DRIVER */ 241 } 242 243 NCURSES_EXPORT(int) 244 _nc_ospeed(int BaudRate) 245 { 246 int result = 1; 247 #if defined(EXP_WIN32_DRIVER) 248 (void) BaudRate; 249 #else 250 if (BaudRate >= 0) { 251 unsigned i; 252 253 for (i = 0; i < SIZEOF(speeds); i++) { 254 if (speeds[i].actual_speed == BaudRate) { 255 result = speeds[i].given_speed; 256 break; 257 } 258 } 259 } 260 #endif 261 return (result); 262 } 263 264 NCURSES_EXPORT(int) 265 NCURSES_SP_NAME(baudrate) (NCURSES_SP_DCL0) 266 { 267 int result; 268 269 T((T_CALLED("baudrate(%p)"), (void *) SP_PARM)); 270 271 #if defined(EXP_WIN32_DRIVER) 272 result = OK; 273 #else 274 /* 275 * In debugging, allow the environment symbol to override when we're 276 * redirecting to a file, so we can construct repeatable test-cases 277 * that take into account costs that depend on baudrate. 278 */ 279 #ifdef TRACE 280 if (IsValidTIScreen(SP_PARM) 281 && !NC_ISATTY(fileno((SP_PARM && SP_PARM->_ofp) ? SP_PARM->_ofp : stdout)) 282 && getenv("BAUDRATE") != 0) { 283 int ret; 284 if ((ret = _nc_getenv_num("BAUDRATE")) <= 0) 285 ret = 9600; 286 ospeed = (NCURSES_OSPEED) _nc_ospeed(ret); 287 returnCode(ret); 288 } 289 #endif 290 291 if (IsValidTIScreen(SP_PARM)) { 292 #ifdef USE_OLD_TTY 293 result = (int) cfgetospeed(&(TerminalOf(SP_PARM)->Nttyb)); 294 ospeed = (NCURSES_OSPEED) _nc_ospeed(result); 295 #else /* !USE_OLD_TTY */ 296 #ifdef TERMIOS 297 ospeed = (NCURSES_OSPEED) cfgetospeed(&(TerminalOf(SP_PARM)->Nttyb)); 298 #else 299 ospeed = (NCURSES_OSPEED) TerminalOf(SP_PARM)->Nttyb.sg_ospeed; 300 #endif 301 result = _nc_baudrate(ospeed); 302 #endif 303 TerminalOf(SP_PARM)->_baudrate = result; 304 } else { 305 result = ERR; 306 } 307 #endif /* !EXP_WIN32_DRIVER */ 308 returnCode(result); 309 } 310 311 #if NCURSES_SP_FUNCS 312 NCURSES_EXPORT(int) 313 baudrate(void) 314 { 315 return NCURSES_SP_NAME(baudrate) (CURRENT_SCREEN); 316 } 317 #endif 318