Module Picos_io.Unix

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.

type file_descr = Picos_io_fd.t

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.

val close : file_descr -> unit

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.

val close_pair : (file_descr * file_descr) -> unit

close_pair (fd1, fd2) is equivalent to close fd1; close fd2.

type error = Unix.error =
  1. | E2BIG
  2. | EACCES
  3. | EAGAIN
  4. | EBADF
  5. | EBUSY
  6. | ECHILD
  7. | EDEADLK
  8. | EDOM
  9. | EEXIST
  10. | EFAULT
  11. | EFBIG
  12. | EINTR
  13. | EINVAL
  14. | EIO
  15. | EISDIR
  16. | EMFILE
  17. | ENAMETOOLONG
  18. | ENFILE
  19. | ENODEV
  20. | ENOENT
  21. | ENOEXEC
  22. | ENOLCK
  23. | ENOMEM
  24. | ENOSPC
  25. | ENOSYS
  26. | ENOTDIR
  27. | ENOTEMPTY
  28. | ENOTTY
  29. | ENXIO
  30. | EPERM
  31. | EPIPE
  32. | ERANGE
  33. | EROFS
  34. | ESPIPE
  35. | ESRCH
  36. | EXDEV
  37. | EWOULDBLOCK
  38. | EINPROGRESS
  39. | EALREADY
  40. | ENOTSOCK
  41. | EDESTADDRREQ
  42. | EMSGSIZE
  43. | EPROTOTYPE
  44. | ENOPROTOOPT
  45. | EPROTONOSUPPORT
  46. | ESOCKTNOSUPPORT
  47. | EOPNOTSUPP
  48. | EPFNOSUPPORT
  49. | EAFNOSUPPORT
  50. | EADDRINUSE
  51. | EADDRNOTAVAIL
  52. | ENETDOWN
  53. | ENETUNREACH
  54. | ENETRESET
  55. | ECONNABORTED
  56. | ECONNRESET
  57. | ENOBUFS
  58. | EISCONN
  59. | ENOTCONN
  60. | ESHUTDOWN
  61. | ETOOMANYREFS
  62. | ETIMEDOUT
  63. | ECONNREFUSED
  64. | EHOSTDOWN
  65. | EHOSTUNREACH
  66. | ELOOP
  67. | EOVERFLOW
  68. | 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 =
  1. | WEXITED of int
  2. | WSIGNALED of int
  3. | WSTOPPED of int
type wait_flag = Unix.wait_flag =
  1. | WNOHANG
  2. | 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 fork : unit -> int
val wait : unit -> int * process_status
val waitpid : wait_flag list -> int -> int * process_status
val system : string -> process_status
val _exit : int -> 'a
val getpid : unit -> int
val getppid : unit -> int
val nice : int -> int
val stdin : file_descr
val stdout : file_descr
val stderr : file_descr
type open_flag = Unix.open_flag =
  1. | O_RDONLY
  2. | O_WRONLY
  3. | O_RDWR
  4. | O_NONBLOCK
  5. | O_APPEND
  6. | O_CREAT
  7. | O_TRUNC
  8. | O_EXCL
  9. | O_NOCTTY
  10. | O_DSYNC
  11. | O_SYNC
  12. | O_RSYNC
  13. | O_SHARE_DELETE
  14. | O_CLOEXEC
  15. | O_KEEPEXEC
type file_perm = int
val openfile : string -> open_flag list -> file_perm -> file_descr
val fsync : file_descr -> unit
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 =
  1. | SEEK_SET
  2. | SEEK_CUR
  3. | SEEK_END
val lseek : file_descr -> int -> seek_command -> int
val truncate : string -> int -> unit
val ftruncate : file_descr -> int -> unit
type file_kind = Unix.file_kind =
  1. | S_REG
  2. | S_DIR
  3. | S_CHR
  4. | S_BLK
  5. | S_LNK
  6. | S_FIFO
  7. | S_SOCK
type stats = Unix.stats = {
  1. st_dev : int;
  2. st_ino : int;
  3. st_kind : file_kind;
  4. st_perm : file_perm;
  5. st_uid : int;
  6. st_gid : int;
  7. st_rdev : int;
  8. st_size : int;
  9. st_atime : float;
  10. st_mtime : float;
  11. st_ctime : float;
}
val stat : string -> stats
val lstat : string -> stats
val fstat : file_descr -> stats
val isatty : file_descr -> bool
module LargeFile : sig ... end
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 rename : string -> string -> unit
val realpath : string -> string
type access_permission = Unix.access_permission =
  1. | R_OK
  2. | W_OK
  3. | X_OK
  4. | F_OK
val chmod : string -> file_perm -> unit
val fchmod : file_descr -> file_perm -> unit
val chown : string -> int -> int -> unit
val fchown : file_descr -> int -> int -> unit
val umask : file_perm -> file_perm
val access : string -> access_permission list -> unit
val dup : ?cloexec:bool -> file_descr -> file_descr
val dup2 : ?cloexec:bool -> file_descr -> file_descr -> unit
val set_nonblock : file_descr -> unit
val clear_nonblock : file_descr -> unit
val set_close_on_exec : file_descr -> unit
val clear_close_on_exec : file_descr -> unit
val mkdir : string -> file_perm -> unit
val rmdir : string -> unit
val chdir : string -> unit
val getcwd : unit -> string
val chroot : string -> unit
type dir_handle = Unix.dir_handle
val opendir : string -> dir_handle
val readdir : dir_handle -> string
val rewinddir : dir_handle -> unit
val closedir : dir_handle -> unit
val pipe : ?cloexec:bool -> unit -> file_descr * file_descr
val mkfifo : string -> file_perm -> unit
val create_process : string -> string array -> file_descr -> file_descr -> file_descr -> int
val create_process_env : string -> string array -> string array -> file_descr -> file_descr -> file_descr -> int
val select : file_descr list -> file_descr list -> file_descr list -> float -> file_descr list * file_descr list * file_descr list

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 =
  1. | F_ULOCK
  2. | F_LOCK
  3. | F_TLOCK
  4. | F_TEST
  5. | F_RLOCK
  6. | F_TRLOCK
val lockf : file_descr -> lock_command -> int -> unit
val kill : int -> int -> unit
type sigprocmask_command = Unix.sigprocmask_command =
  1. | SIG_SETMASK
  2. | SIG_BLOCK
  3. | SIG_UNBLOCK
val sigprocmask : sigprocmask_command -> int list -> int list
val sigpending : unit -> int list
type process_times = Unix.process_times = {
  1. tms_utime : float;
  2. tms_stime : float;
  3. tms_cutime : float;
  4. tms_cstime : float;
}
type tm = Unix.tm = {
  1. tm_sec : int;
  2. tm_min : int;
  3. tm_hour : int;
  4. tm_mday : int;
  5. tm_mon : int;
  6. tm_year : int;
  7. tm_wday : int;
  8. tm_yday : int;
  9. tm_isdst : bool;
}
val time : unit -> float
val gettimeofday : unit -> float
val gmtime : float -> tm
val localtime : float -> tm
val mktime : tm -> float * tm
val alarm : int -> int
val sleep : int -> unit
val sleepf : float -> unit
val times : unit -> process_times
val utimes : string -> float -> float -> unit
type interval_timer = Unix.interval_timer =
  1. | ITIMER_REAL
  2. | ITIMER_VIRTUAL
  3. | ITIMER_PROF
type interval_timer_status = Unix.interval_timer_status = {
  1. it_interval : float;
  2. it_value : float;
}
val getuid : unit -> int
val geteuid : unit -> int
val setuid : int -> unit
val getgid : unit -> int
val getegid : unit -> int
val setgid : int -> unit
val getgroups : unit -> int array
val setgroups : int array -> unit
val initgroups : string -> int -> unit
type passwd_entry = Unix.passwd_entry = {
  1. pw_name : string;
  2. pw_passwd : string;
  3. pw_uid : int;
  4. pw_gid : int;
  5. pw_gecos : string;
  6. pw_dir : string;
  7. pw_shell : string;
}
type group_entry = Unix.group_entry = {
  1. gr_name : string;
  2. gr_passwd : string;
  3. gr_gid : int;
  4. gr_mem : string array;
}
val getlogin : unit -> string
val getpwnam : string -> passwd_entry
val getgrnam : string -> group_entry
val getpwuid : int -> passwd_entry
val getgrgid : int -> group_entry
type inet_addr = Unix.inet_addr
val inet_addr_of_string : string -> inet_addr
val string_of_inet_addr : inet_addr -> string
val inet_addr_any : inet_addr
val inet_addr_loopback : inet_addr
val inet6_addr_any : inet_addr
val inet6_addr_loopback : inet_addr
val is_inet6_addr : inet_addr -> bool
type socket_domain = Unix.socket_domain =
  1. | PF_UNIX
  2. | PF_INET
  3. | PF_INET6
type socket_type = Unix.socket_type =
  1. | SOCK_STREAM
  2. | SOCK_DGRAM
  3. | SOCK_RAW
  4. | SOCK_SEQPACKET
type sockaddr = Unix.sockaddr =
  1. | ADDR_UNIX of string
  2. | ADDR_INET of inet_addr * int
val socket : ?cloexec:bool -> socket_domain -> socket_type -> int -> file_descr
val domain_of_sockaddr : sockaddr -> socket_domain
val socketpair : ?cloexec:bool -> socket_domain -> socket_type -> int -> file_descr * file_descr
val accept : ?cloexec:bool -> file_descr -> file_descr * sockaddr
val bind : file_descr -> sockaddr -> unit
val connect : file_descr -> sockaddr -> unit
val listen : file_descr -> int -> unit
type shutdown_command = Unix.shutdown_command =
  1. | SHUTDOWN_RECEIVE
  2. | SHUTDOWN_SEND
  3. | SHUTDOWN_ALL
val shutdown : file_descr -> shutdown_command -> unit
val getsockname : file_descr -> sockaddr
val getpeername : file_descr -> sockaddr
type msg_flag = Unix.msg_flag =
  1. | MSG_OOB
  2. | MSG_DONTROUTE
  3. | MSG_PEEK
val recv : file_descr -> bytes -> int -> int -> msg_flag list -> int
val recvfrom : file_descr -> bytes -> int -> int -> msg_flag list -> int * sockaddr
val send : file_descr -> bytes -> int -> int -> msg_flag list -> int
val send_substring : file_descr -> string -> int -> int -> msg_flag list -> int
val sendto : file_descr -> bytes -> int -> int -> msg_flag list -> sockaddr -> int
val sendto_substring : file_descr -> string -> int -> int -> msg_flag list -> sockaddr -> int
type socket_bool_option = Unix.socket_bool_option =
  1. | SO_DEBUG
  2. | SO_BROADCAST
  3. | SO_REUSEADDR
  4. | SO_KEEPALIVE
  5. | SO_DONTROUTE
  6. | SO_OOBINLINE
  7. | SO_ACCEPTCONN
  8. | TCP_NODELAY
  9. | IPV6_ONLY
  10. | SO_REUSEPORT
type socket_int_option = Unix.socket_int_option =
  1. | SO_SNDBUF
  2. | SO_RCVBUF
  3. | SO_ERROR
    (*
    • deprecated Use Unix.getsockopt_error instead.
    *)
  4. | SO_TYPE
  5. | SO_RCVLOWAT
  6. | SO_SNDLOWAT
type socket_optint_option = Unix.socket_optint_option =
  1. | SO_LINGER
type socket_float_option = Unix.socket_float_option =
  1. | SO_RCVTIMEO
  2. | SO_SNDTIMEO
val getsockopt : file_descr -> socket_bool_option -> bool
val setsockopt : file_descr -> socket_bool_option -> bool -> unit
val getsockopt_int : file_descr -> socket_int_option -> int
val setsockopt_int : file_descr -> socket_int_option -> int -> unit
val getsockopt_optint : file_descr -> socket_optint_option -> int option
val setsockopt_optint : file_descr -> socket_optint_option -> int option -> unit
val getsockopt_float : file_descr -> socket_float_option -> float
val setsockopt_float : file_descr -> socket_float_option -> float -> unit
val getsockopt_error : file_descr -> error option
type host_entry = Unix.host_entry = {
  1. h_name : string;
  2. h_aliases : string array;
  3. h_addrtype : socket_domain;
  4. h_addr_list : inet_addr array;
}
type protocol_entry = Unix.protocol_entry = {
  1. p_name : string;
  2. p_aliases : string array;
  3. p_proto : int;
}
type service_entry = Unix.service_entry = {
  1. s_name : string;
  2. s_aliases : string array;
  3. s_port : int;
  4. s_proto : string;
}
val gethostname : unit -> string
val gethostbyname : string -> host_entry
val gethostbyaddr : inet_addr -> host_entry
val getprotobyname : string -> protocol_entry
val getprotobynumber : int -> protocol_entry
val getservbyname : string -> string -> service_entry
val getservbyport : int -> string -> service_entry
type addr_info = Unix.addr_info = {
  1. ai_family : socket_domain;
  2. ai_socktype : socket_type;
  3. ai_protocol : int;
  4. ai_addr : sockaddr;
  5. ai_canonname : string;
}
type getaddrinfo_option = Unix.getaddrinfo_option =
  1. | AI_FAMILY of socket_domain
  2. | AI_SOCKTYPE of socket_type
  3. | AI_PROTOCOL of int
  4. | AI_NUMERICHOST
  5. | AI_CANONNAME
  6. | AI_PASSIVE
val getaddrinfo : string -> string -> getaddrinfo_option list -> addr_info list
type name_info = Unix.name_info = {
  1. ni_hostname : string;
  2. ni_service : string;
}
type getnameinfo_option = Unix.getnameinfo_option =
  1. | NI_NOFQDN
  2. | NI_NUMERICHOST
  3. | NI_NAMEREQD
  4. | NI_NUMERICSERV
  5. | NI_DGRAM
val getnameinfo : sockaddr -> getnameinfo_option list -> name_info
type terminal_io = Unix.terminal_io = {
  1. mutable c_ignbrk : bool;
  2. mutable c_brkint : bool;
  3. mutable c_ignpar : bool;
  4. mutable c_parmrk : bool;
  5. mutable c_inpck : bool;
  6. mutable c_istrip : bool;
  7. mutable c_inlcr : bool;
  8. mutable c_igncr : bool;
  9. mutable c_icrnl : bool;
  10. mutable c_ixon : bool;
  11. mutable c_ixoff : bool;
  12. mutable c_opost : bool;
  13. mutable c_obaud : int;
  14. mutable c_ibaud : int;
  15. mutable c_csize : int;
  16. mutable c_cstopb : int;
  17. mutable c_cread : bool;
  18. mutable c_parenb : bool;
  19. mutable c_parodd : bool;
  20. mutable c_hupcl : bool;
  21. mutable c_clocal : bool;
  22. mutable c_isig : bool;
  23. mutable c_icanon : bool;
  24. mutable c_noflsh : bool;
  25. mutable c_echo : bool;
  26. mutable c_echoe : bool;
  27. mutable c_echok : bool;
  28. mutable c_echonl : bool;
  29. mutable c_vintr : char;
  30. mutable c_vquit : char;
  31. mutable c_verase : char;
  32. mutable c_vkill : char;
  33. mutable c_veof : char;
  34. mutable c_veol : char;
  35. mutable c_vmin : int;
  36. mutable c_vtime : int;
  37. mutable c_vstart : char;
  38. mutable c_vstop : char;
}
val tcgetattr : file_descr -> terminal_io
type setattr_when = Unix.setattr_when =
  1. | TCSANOW
  2. | TCSADRAIN
  3. | TCSAFLUSH
val tcsetattr : file_descr -> setattr_when -> terminal_io -> unit
val tcsendbreak : file_descr -> int -> unit
val tcdrain : file_descr -> unit
type flush_queue = Unix.flush_queue =
  1. | TCIFLUSH
  2. | TCOFLUSH
  3. | TCIOFLUSH
val tcflush : file_descr -> flush_queue -> unit
type flow_action = Unix.flow_action =
  1. | TCOOFF
  2. | TCOON
  3. | TCIOFF
  4. | TCION
val tcflow : file_descr -> flow_action -> unit
val setsid : unit -> int