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 87MODULE_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 97struct 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 105static 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 194NCURSES_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 243NCURSES_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 264NCURSES_EXPORT(int) 265NCURSES_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 312NCURSES_EXPORT(int) 313baudrate(void) 314{ 315 return NCURSES_SP_NAME(baudrate) (CURRENT_SCREEN); 316} 317#endif 318