A transparently asynchronous replacement for a subset of the Unix
module that comes with OCaml.
In this module operations on file descriptors, such as read
and write
and others, including select
, implicitly block, in a scheduler friendly manner, to await for the file descriptor to become available for the operation. This works best with file descriptors set to non-blocking mode .
In addition to operations on file descriptors, in this module
also block in a scheduler friendly manner. Additionally
also block in a scheduler friendly manner except on Windows.
⚠️ Shared (i.e. inherited or inheritable or duplicated ) file descriptors, such as stdin
, stdout
, and stderr
, typically should not be put into non-blocking mode, because that affects all of the parties using the shared file descriptors. However, for non-shared file descriptors non-blocking mode improves performance significantly with this module.
⚠️ Beware that this does not currently try to work around any limitations of the Unix
module that comes with OCaml. In particular, on Windows, only sockets can be put into non-blocking mode. Also, on Windows, scheduler friendly blocking only works properly with non-blocking file descriptors, i.e. sockets.
⚠️ This module uses Picos_io_select
and you may need to configure it at start of your application.
Please consult the documentation of the Unix
module that comes with OCaml.
Opaque type alias for Unix.file_descr
.
⚠️ Please consider the reference counting of file descriptors as an internal implementation detail and avoid depending on it.
close file_descr
marks the file descriptor as to be closed.
ℹ️ The file descriptor will either be closed immediately or after all concurrently running transparently asynchronous operations with the file descriptor have finished.
⚠️ After calling close
no new operations should be started with the file descriptor.
type error = Unix .error =
| E2BIG
| EACCES
| EAGAIN
| EBADF
| EBUSY
| ECHILD
| EDEADLK
| EDOM
| EEXIST
| EFAULT
| EFBIG
| EINTR
| EINVAL
| EIO
| EISDIR
| EMFILE
| EMLINK
| ENAMETOOLONG
| ENFILE
| ENODEV
| ENOENT
| ENOEXEC
| ENOLCK
| ENOMEM
| ENOSPC
| ENOSYS
| ENOTDIR
| ENOTEMPTY
| ENOTTY
| ENXIO
| EPERM
| EPIPE
| ERANGE
| EROFS
| ESPIPE
| ESRCH
| EXDEV
| EWOULDBLOCK
| EINPROGRESS
| EALREADY
| ENOTSOCK
| EDESTADDRREQ
| EMSGSIZE
| EPROTOTYPE
| ENOPROTOOPT
| EPROTONOSUPPORT
| ESOCKTNOSUPPORT
| EOPNOTSUPP
| EPFNOSUPPORT
| EAFNOSUPPORT
| EADDRINUSE
| EADDRNOTAVAIL
| ENETDOWN
| ENETUNREACH
| ENETRESET
| ECONNABORTED
| ECONNRESET
| ENOBUFS
| EISCONN
| ENOTCONN
| ESHUTDOWN
| ETOOMANYREFS
| ETIMEDOUT
| ECONNREFUSED
| EHOSTDOWN
| EHOSTUNREACH
| ELOOP
| EOVERFLOW
| EUNKNOWNERR of int
exception Unix_error of error * string * string
val error_message : error -> string
val handle_unix_error : ('a -> 'b ) -> 'a -> 'b
val environment : unit -> string array
val unsafe_environment : unit -> string array
val getenv : string -> string
val unsafe_getenv : string -> string
val putenv : string -> string -> unit
type process_status = Unix .process_status =
| WEXITED of int
| WSIGNALED of int
| WSTOPPED of int
type wait_flag = Unix .wait_flag =
| WNOHANG
| WUNTRACED
val execv : string -> string array -> 'a
val execve : string -> string array -> string array -> 'a
val execvp : string -> string array -> 'a
val execvpe : string -> string array -> string array -> 'a
val getppid : unit -> int
type open_flag = Unix .open_flag =
| O_RDONLY
| O_WRONLY
| O_RDWR
| O_NONBLOCK
| O_APPEND
| O_CREAT
| O_TRUNC
| O_EXCL
| O_NOCTTY
| O_DSYNC
| O_SYNC
| O_RSYNC
| O_SHARE_DELETE
| O_CLOEXEC
| O_KEEPEXEC
val read : file_descr -> bytes -> int -> int -> int
val write : file_descr -> bytes -> int -> int -> int
val single_write : file_descr -> bytes -> int -> int -> int
val write_substring : file_descr -> string -> int -> int -> int
val single_write_substring : file_descr -> string -> int -> int -> int
type seek_command = Unix .seek_command =
| SEEK_SET
| SEEK_CUR
| SEEK_END
val truncate : string -> int -> unit
type file_kind = Unix .file_kind =
| S_REG
| S_DIR
| S_CHR
| S_BLK
| S_LNK
| S_FIFO
| S_SOCK
type stats = Unix .stats = {
st_dev : int;
st_ino : int;
st_kind : file_kind ;
st_perm : file_perm ;
st_nlink : int;
st_uid : int;
st_gid : int;
st_rdev : int;
st_size : int;
st_atime : float;
st_mtime : float;
st_ctime : float;
}
val stat : string -> stats
val lstat : string -> stats
val map_file :
file_descr ->
?pos :int64 ->
('a , 'b ) Stdlib .Bigarray.kind ->
'c Stdlib .Bigarray.layout ->
bool ->
int array ->
('a , 'b , 'c ) Stdlib .Bigarray.Genarray.t
val unlink : string -> unit
val rename : string -> string -> unit
val link : ?follow :bool -> string -> string -> unit
val realpath : string -> string
type access_permission = Unix .access_permission =
| R_OK
| W_OK
| X_OK
| F_OK
val chown : string -> int -> int -> unit
val rmdir : string -> unit
val chdir : string -> unit
val getcwd : unit -> string
val chroot : string -> unit
type dir_handle = Unix .dir_handle
val symlink : ?to_dir :bool -> string -> string -> unit
val has_symlink : unit -> bool
val readlink : string -> string
select rds wrs exs timeout
is like Deps.Unix.select
, but uses Picos_io_select
to avoid blocking the thread.
🐌 You may find composing multi file descriptor awaits via other means with Picos_io_select
more flexible and efficient.
type lock_command = Unix .lock_command =
| F_ULOCK
| F_LOCK
| F_TLOCK
| F_TEST
| F_RLOCK
| F_TRLOCK
val kill : int -> int -> unit
type sigprocmask_command = Unix .sigprocmask_command =
| SIG_SETMASK
| SIG_BLOCK
| SIG_UNBLOCK
val sigpending : unit -> int list
type process_times = Unix .process_times = {
tms_utime : float;
tms_stime : float;
tms_cutime : float;
tms_cstime : float;
}
type tm = Unix .tm = {
tm_sec : int;
tm_min : int;
tm_hour : int;
tm_mday : int;
tm_mon : int;
tm_year : int;
tm_wday : int;
tm_yday : int;
tm_isdst : bool;
}
val gettimeofday : unit -> float
val localtime : float -> tm
val mktime : tm -> float * tm
val sleepf : float -> unit
val utimes : string -> float -> float -> unit
type interval_timer = Unix .interval_timer =
| ITIMER_REAL
| ITIMER_VIRTUAL
| ITIMER_PROF
type interval_timer_status = Unix .interval_timer_status = {
it_interval : float;
it_value : float;
}
val geteuid : unit -> int
val getegid : unit -> int
val getgroups : unit -> int array
val setgroups : int array -> unit
val initgroups : string -> int -> unit
type passwd_entry = Unix .passwd_entry = {
pw_name : string;
pw_passwd : string;
pw_uid : int;
pw_gid : int;
pw_gecos : string;
pw_dir : string;
pw_shell : string;
}
type group_entry = Unix .group_entry = {
gr_name : string;
gr_passwd : string;
gr_gid : int;
gr_mem : string array ;
}
val getlogin : unit -> string
type inet_addr = Unix .inet_addr
val inet_addr_of_string : string -> inet_addr
val string_of_inet_addr : inet_addr -> string
type socket_domain = Unix .socket_domain =
| PF_UNIX
| PF_INET
| PF_INET6
type socket_type = Unix .socket_type =
| SOCK_STREAM
| SOCK_DGRAM
| SOCK_RAW
| SOCK_SEQPACKET
type sockaddr = Unix .sockaddr =
| ADDR_UNIX of string
| ADDR_INET of inet_addr * int
type shutdown_command = Unix .shutdown_command =
| SHUTDOWN_RECEIVE
| SHUTDOWN_SEND
| SHUTDOWN_ALL
type msg_flag = Unix .msg_flag =
| MSG_OOB
| MSG_DONTROUTE
| MSG_PEEK
type socket_bool_option = Unix .socket_bool_option =
| SO_DEBUG
| SO_BROADCAST
| SO_REUSEADDR
| SO_KEEPALIVE
| SO_DONTROUTE
| SO_OOBINLINE
| SO_ACCEPTCONN
| TCP_NODELAY
| IPV6_ONLY
| SO_REUSEPORT
type socket_int_option = Unix .socket_int_option =
| SO_SNDBUF
| SO_RCVBUF
| SO_ERROR
| SO_TYPE
| SO_RCVLOWAT
| SO_SNDLOWAT
type socket_optint_option = Unix .socket_optint_option =
| SO_LINGER
type socket_float_option = Unix .socket_float_option =
| SO_RCVTIMEO
| SO_SNDTIMEO
type host_entry = Unix .host_entry = {
h_name : string;
h_aliases : string array ;
h_addrtype : socket_domain ;
h_addr_list : inet_addr array ;
}
type protocol_entry = Unix .protocol_entry = {
p_name : string;
p_aliases : string array ;
p_proto : int;
}
type service_entry = Unix .service_entry = {
s_name : string;
s_aliases : string array ;
s_port : int;
s_proto : string;
}
val gethostname : unit -> string
type getaddrinfo_option = Unix .getaddrinfo_option =
| AI_FAMILY of socket_domain
| AI_SOCKTYPE of socket_type
| AI_PROTOCOL of int
| AI_NUMERICHOST
| AI_CANONNAME
| AI_PASSIVE
type name_info = Unix .name_info = {
ni_hostname : string;
ni_service : string;
}
type getnameinfo_option = Unix .getnameinfo_option =
| NI_NOFQDN
| NI_NUMERICHOST
| NI_NAMEREQD
| NI_NUMERICSERV
| NI_DGRAM
type terminal_io = Unix .terminal_io = {
mutable c_ignbrk : bool;
mutable c_brkint : bool;
mutable c_ignpar : bool;
mutable c_parmrk : bool;
mutable c_inpck : bool;
mutable c_istrip : bool;
mutable c_inlcr : bool;
mutable c_igncr : bool;
mutable c_icrnl : bool;
mutable c_ixon : bool;
mutable c_ixoff : bool;
mutable c_opost : bool;
mutable c_obaud : int;
mutable c_ibaud : int;
mutable c_csize : int;
mutable c_cstopb : int;
mutable c_cread : bool;
mutable c_parenb : bool;
mutable c_parodd : bool;
mutable c_hupcl : bool;
mutable c_clocal : bool;
mutable c_isig : bool;
mutable c_icanon : bool;
mutable c_noflsh : bool;
mutable c_echo : bool;
mutable c_echoe : bool;
mutable c_echok : bool;
mutable c_echonl : bool;
mutable c_vintr : char;
mutable c_vquit : char;
mutable c_verase : char;
mutable c_vkill : char;
mutable c_veof : char;
mutable c_veol : char;
mutable c_vmin : int;
mutable c_vtime : int;
mutable c_vstart : char;
mutable c_vstop : char;
}
type setattr_when = Unix .setattr_when =
| TCSANOW
| TCSADRAIN
| TCSAFLUSH
type flush_queue = Unix .flush_queue =
| TCIFLUSH
| TCOFLUSH
| TCIOFLUSH
type flow_action = Unix .flow_action =
| TCOOFF
| TCOON
| TCIOFF
| TCION