package tty

  1. Overview
  2. Docs

Source file stdin.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
let stdin_fd = Unix.descr_of_in_channel stdin
let decoder = Uutf.decoder ~encoding:`UTF_8 `Manual

let set_raw_mode () =
  let termios = Unix.tcgetattr stdin_fd in
  let new_termios =
    Unix.
      { termios with c_icanon = false; c_echo = false; c_vmin = 1; c_vtime = 0 }
  in
  Unix.tcsetattr stdin_fd TCSANOW new_termios;
  termios

let restore_mode termios = Unix.tcsetattr stdin_fd TCSANOW termios

let try_read () =
  let bytes = Bytes.create 8 in
  let ready, _, _ = Unix.select [ stdin_fd ] [] [] 0.0001 in
  if ready = [] then ()
  else
    match Unix.read stdin_fd bytes 0 8 with
    | exception Unix.(Unix_error ((EINTR | EAGAIN | EWOULDBLOCK), _, _)) -> ()
    | len -> Uutf.Manual.src decoder bytes 0 len

let uchar_to_str u =
  let buf = Buffer.create 8 in
  Uutf.Buffer.add_utf_8 buf u;
  Buffer.contents buf

let read_utf8 () =
  match Uutf.decode decoder with
  | `Uchar u -> `Read (uchar_to_str u)
  | `End -> `End
  | `Await ->
      try_read ();
      `Retry
  | `Malformed err -> `Malformed err

let setup () = set_raw_mode ()
let shutdown termios = restore_mode termios
OCaml

Innovation. Community. Security.