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