hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };