termios.ha (2404B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use errors; 5 use io; 6 use rt; 7 8 export type termios = struct { 9 file: io::file, 10 saved: rt::termios, 11 current: rt::termios, 12 }; 13 14 // Retrieves serial port settings of the given terminal. 15 export fn termios_query(file: io::file) (termios | errors::error) = { 16 let settings = rt::termios { ... }; 17 18 match (rt::ioctl(file, rt::TIOCGETA, &settings)) { 19 case int => void; 20 case let err: rt::errno => 21 return errors::errno(err); 22 }; 23 24 return termios { 25 file = file, 26 saved = settings, 27 current = settings, 28 }; 29 }; 30 31 // Restores original serial port settings. 32 export fn termios_restore(termios: *const termios) void = { 33 rt::ioctl(termios.file, rt::TIOCSETA, &termios.saved): void; 34 }; 35 36 // Sets serial port settings. 37 export fn termios_set(termios: *const termios) (void | errors::error) = { 38 match (rt::ioctl(termios.file, rt::TIOCSETA, &termios.current)) { 39 case int => void; 40 case let err: rt::errno => 41 return errors::errno(err); 42 }; 43 }; 44 45 // Enables "raw" mode for this terminal, disabling echoing, line 46 // editing, and signal handling. Users should call [[termios_query]] 47 // prior to this to save the previous terminal settings, and 48 // [[termios_restore]] to restore them before exiting. 49 export fn makeraw(termios: *termios) (void | errors::error) = { 50 // Disable break signal and CR<->LF processing 51 termios.current.c_iflag &= ~(rt::tcflag::IGNBRK | rt::tcflag::BRKINT 52 | rt::tcflag::INLCR | rt::tcflag::IGNCR 53 | rt::tcflag::ICRNL); 54 // Disable output post-processing 55 termios.current.c_oflag &= ~rt::tcflag::OPOST; 56 // Disable character echo, canonical mode, implementation defined 57 // extensions and INTR/QUIT/SUSP characters 58 termios.current.c_lflag &= ~(rt::tcflag::ECHO | rt::tcflag::ECHONL 59 | rt::tcflag::ICANON | rt::tcflag::IEXTEN 60 | rt::tcflag::ISIG); 61 62 termios_set(termios)?; 63 }; 64 65 // Disables "echo" on this terminal. Users should call [[termios_restore]] to 66 // restore settings. 67 export fn noecho(termios: *termios) (void | errors::error) = { 68 termios.current.c_lflag &= ~rt::tcflag::ECHO; 69 termios_set(termios)?; 70 }; 71 72 // Enables "noncanonical" mode for this terminal, disabling line buffering and 73 // line editing. Users should call [[termios_restore]] to restore settings. 74 export fn noncanonical(termios: *termios) (void | errors::error) = { 75 termios.current.c_lflag &= ~rt::tcflag::ICANON; 76 termios_set(termios)?; 77 };