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