Uwt.TtyTTY handles represent a stream for the console.
include module type of Stream with type t := tinclude module type of Handle with type t := tval close : t -> Int_result.unitHandles are closed automatically, if they are not longer referenced from the OCaml heap. Nevertheless, you should nearly always close them with close, because:
However, it's safe to write code in this manner:
let s = Uwt.Tcp.init () in
let c = Uwt.Tcp.init () in
Uwt.Tcp.nodelay s false;
Uwt.Tcp.simultaneous_accepts true;
if foobar () then (* no file descriptor yet assigned, no need to worry
about exceptions inside foobar,... *)
Lwt.return_unit (* no need to close *)
else
...If you want - for whatever reason - keep a file descriptor open for the whole lifetime of your process, remember to keep a reference to its handle.
val close_noerr : t -> unitPrefer close or close_noerr to close_wait. close or close_noerr return immediately (there are no useful error messages, beside perhaps a notice, that you've already closed that handle).
close_wait is only useful, if you intend to wait until all concurrent write and read threads related to this handle are canceled.
val is_active : t -> boolReturns non-zero if the handle is active, zero if it's inactive. What "active" means depends on the type of handle:
Async.t handle is always active and cannot be deactivated, except by closing it with uv_close().Pipe.t, Tcp.t, Udp.t, etc. handle - basically any handle that deals with i/o - is active when it is doing something that involves i/o, like reading, writing, connecting, accepting new connections, etc.Rule of thumb: if a handle of type Uwt.Foo.t has a uv_foo_start() function, then it's active from the moment that function is called. Likewise, uv_foo_stop() deactivates the handle again.
val ref' : t -> unitReference the given handle. References are idempotent, that is, if a handle is already referenced calling this function again will have no effect.
val unref : t -> unitUn-reference the given handle. References are idempotent, that is, if a handle is not referenced calling this function again will have no effect.
val has_ref : t -> boolReturns non-zero if the handle is referenced, zero otherwise.
val is_readable : t -> boolval is_writable : t -> boolval read_start : t -> cb:(Bytes.t uv_result -> unit) -> Int_result.unitRead data from an incoming stream. The ~cb will be made several times until there is no more data to read or read_stop is called.
val read_stop : t -> Int_result.unitStop reading data from the stream.
val read_stop_exn : t -> unitThere is currently no uv_read function in libuv, just uv_read_start and uv_read_stop. This is a wrapper for your convenience. It calls read_stop internally, if you don't continue with reading immediately. Zero result indicates EOF.
In future libuv versions, there might be uv_read and uv_try_read functions (it was discussed several times). If these changes got merged, Stream.read will wrap them - even if there will be small semantic differences.
It is currently not possible to start several read threads in parallel, you must serialize the requests manually. In the following example t2 will fail with EBUSY:
let t1 = Uwt.Stream.read t ~buf:buf1 in
let t2 = Uwt.Stream.read t ~buf:buf2 in
(* ... *)Calling the function with ~len:0 has a dubious, system dependent semantic.
val write_queue_size : t -> intReturns the amount of queued bytes waiting to be sent
val try_write : ?pos:int -> ?len:int -> t -> buf:bytes -> Int_result.intWrite data to stream, but won't queue a write request if it can't be completed immediately.
val try_write_ba : ?pos:int -> ?len:int -> t -> buf:buf -> Int_result.intval try_write_string :
?pos:int ->
?len:int ->
t ->
buf:string ->
Int_result.intwrite is eager - like the counterparts inside Lwt_unix. It first calls try_write internally to check if it can return immediately (without the overhead of creating a sleeping thread and waking it up later). If it can't write everything instantly, it will call write_raw internally. write_raw is exposed here mainly in order to write unit tests for it. But you can also use it, if you your ~buf is very large or you know for another reason, that try_write will fail.
val try_writev : t -> Iovec_write.t list -> Int_result.intWindows doesn't support writing multiple buffers with a single syscall for some HANDLEs (e.g. it's supported for tcp handles, but not pipes). uwt then writes the buffers one by one
If the number of buffers is greater than IOV_MAX, libuv already contains the necessary workarounds
val writev : t -> Iovec_write.t list -> unit Lwt.tSee comment to
y_writev
}
! This function will fail with Unix.EOPNOTSUPP on Windows for e.g. pipe handles
val writev_emul : t -> Iovec_write.t list -> unit Lwt.tSimilar to writev, but if passing several buffers at once is not supported by the OS, the buffers will be written one by one. Please note that as a consequence you should not start several writev_emul threads in parallel. The writing order would be surprising in this case. If you don't use windows, this function is identic to writev
val writev_raw : t -> Iovec_write.t list -> unit Lwt.tval listen :
t ->
max:int ->
cb:(t -> Int_result.unit -> unit) ->
Int_result.unitStart listening for incoming connections. ~max indicates the number of connections the kernel might queue, same as listen(2). When a new incoming connection is received ~cb is called.
val listen_exn : t -> max:int -> cb:(t -> Int_result.unit -> unit) -> unitShutdown the outgoing (write) side of a duplex stream. It waits for pending write requests to complete.
val set_blocking : t -> bool -> Int_result.unitJust don't use this function. It will only cause trouble.
include module type of Handle_fileno with type t := tval fileno : t -> Unix.file_descr uv_resultval fileno_exn : t -> Unix.file_descrInitialize a new TTY stream with the given file descriptor. Usually the file descriptor will be: stdin,stdout or stderr ~read specifies if you plan on calling read_start with this stream. stdin is readable, stdout is not.
On Unix this function will determine the path of the fd of the terminal using ttyname_r(3), open it, and use it if the passed file descriptor refers to a TTY. This lets libuv put the tty in non-blocking mode without affecting other processes that share the tty.
This function is not thread safe on systems that don't support ioctl TIOCGPTN or TIOCPTYGNAME, for instance OpenBSD and Solaris.
Note: If reopening the TTY fails, libuv falls back to blocking writes for non-readable TTY streams.
val set_mode : t -> mode:mode -> Int_result.unitSet the TTY using the specified terminal mode
val reset_mode : unit -> Int_result.unitTo be called when the program exits. Resets TTY settings to default values for the next process to take over.
This function is async signal-safe on Unix platforms but can fail with error code UV_EBUSY if you call it when execution is inside uv_tty_set_mode().