123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564open!ImportopenCore_unixmoduletypeS=sig(** {2 sysinfo} *)moduleSysinfo:sig(** Result of sysinfo syscall (man 2 sysinfo). *)typet={uptime:Time.Span.t;(** Time since boot *)load1:int;(** Load average over the last minute *)load5:int;(** Load average over the last 5 minutes*)load15:int;(** Load average over the last 15 minutes *)total_ram:int;(** Total usable main memory *)free_ram:int;(** Available memory size *)shared_ram:int;(** Amount of shared memory *)buffer_ram:int;(** Memory used by buffers *)total_swap:int;(** Total swap page size *)free_swap:int;(** Available swap space *)procs:int;(** Number of current processes *)totalhigh:int;(** Total high memory size *)freehigh:int;(** Available high memory size *)mem_unit:int;(** Memory unit size in bytes *)}[@@derivingsexp,bin_io]valsysinfo:(unit->t)Or_error.tend(** {2 Filesystem functions} *)(** [sendfile ?pos ?len ~fd sock] sends mmap-able data from file descriptor [fd] to
socket [sock] using offset [pos] and length [len]. Returns the number of characters
actually written.
NOTE: If the returned value is unequal to what was requested (= the initial size of
the data by default), the system call may have been interrupted by a signal, the
source file may have been truncated during operation, or a timeout may have occurred
on the socket during sending. It is currently impossible to find out which of these
events actually happened. Calling {!sendfile} several times on the same descriptor
that only partially accepted data due to a timeout will eventually lead to the Unix
error [EAGAIN].
Raises [Unix_error] on Unix-errors. *)valsendfile:(?pos:int(** Defaults to 0. *)->?len:int(** Defaults to length of data (file) associated with descriptor [fd]. *)->fd:File_descr.t->File_descr.t->int)Or_error.t(** Type for status of SO_BINDTODEVICE socket option. The socket may either restrict the
traffic to a given (by name, e.g. "eth0") interface, or do no restriction at all. *)moduleBound_to_interface:sigtypet=Any|Onlyofstring[@@derivingsexp_of]end(** {2 Non-portable TCP functionality} *)typetcp_bool_option=|TCP_CORK(** (Since Linux 2.2) If set, don’t send out partial frames. All queued partial
frames are sent when the option is cleared again. This is useful for prepending
headers before calling [sendfile(2)], or for throughput optimization. As
currently implemented, there is a 200ms ceiling on the time for which output is
corked by TCP_CORK. If this ceiling is reached, queued data is automatically
transmitted.
This option should not be used in code intended to be portable. *)|TCP_QUICKACK(** (Since Linux 2.4.4) Quick ack solves an unfortunate interaction between the
delayed acks and the Nagle algorithm (TCP_NODELAY). On fast LANs, the Linux TCP
stack quickly reaches a CWND (congestion window) of 1 (Linux interprets this as "1
unacknowledged packet", BSD/Windows and others consider it "1 unacknowledged
segment of data").
If Linux determines a connection to be bidirectional, it will delay sending acks,
hoping to bundle them with other outgoing data. This can lead to serious
connection stalls on, say, a TCP market data connection with one second
heartbeats. TCP_QUICKACK can be used to prevent entering this delayed ack state.
This option should not be used in code intended to be portable. *)[@@derivingsexp,bin_io](** [gettcpopt_bool sock opt] Returns the current value of the boolean TCP socket option
[opt] for socket [sock]. *)valgettcpopt_bool:(File_descr.t->tcp_bool_option->bool)Or_error.t(** [settcpopt_bool sock opt v] sets the current value of the boolean TCP socket option
[opt] for socket [sock] to value [v]. *)valsettcpopt_bool:(File_descr.t->tcp_bool_option->bool->unit)Or_error.t(** [send_nonblocking_no_sigpipe sock ?pos ?len buf] tries to do a nonblocking send on
socket [sock] given buffer [buf], offset [pos] and length [len]. Prevents
[SIGPIPE], i.e., raises a Unix-error in that case immediately. Returns [Some
bytes_written] or [None] if the operation would have blocked.
Raises [Invalid_argument] if the designated buffer range is invalid.
Raises [Unix_error] on Unix-errors. *)valsend_nonblocking_no_sigpipe:(File_descr.t->?pos:int(** default = 0 *)->?len:int(** default = [Bytes.length buf - pos] *)->Bytes.t->intoption)Or_error.t(** [send_no_sigpipe sock ?pos ?len buf] tries to do a blocking send on socket [sock]
given buffer [buf], offset [pos] and length [len]. Prevents [SIGPIPE], i.e., raises
a Unix-error in that case immediately. Returns the number of bytes written.
Raises [Invalid_argument] if the designated buffer range is invalid.
Raises [Unix_error] on Unix-errors. *)valsend_no_sigpipe:(File_descr.t->?pos:int(** default = 0 *)->?len:int(** default = [Bytes.length buf - pos] *)->Bytes.t->int)Or_error.t(** [sendmsg_nonblocking_no_sigpipe sock ?count iovecs] tries to do a nonblocking send
on socket [sock] using [count] I/O-vectors [iovecs]. Prevents [SIGPIPE],
i.e., raises a Unix-error in that case immediately. Returns [Some bytes_written] or
[None] if the operation would have blocked.
Raises [Invalid_argument] if the designated ranges are invalid.
Raises [Unix_error] on Unix-errors. *)valsendmsg_nonblocking_no_sigpipe:(File_descr.t->?count:int->stringIOVec.tarray->intoption)Or_error.t(** {2 Clock functions} *)moduleClock:sigtypet(** All these functions can raise [Unix_error]. *)(** Returns the CPU-clock associated with the thread. *)valget:(Thread.t->t)Or_error.tvalget_time:(t->Time.Span.t)Or_error.tvalset_time:(t->Time.Span.t->unit)Or_error.tvalget_resolution:(t->Time.Span.t)Or_error.t(** The clock measuring the CPU time of a process. *)valget_process_clock:(unit->t)Or_error.t(** The clock measuring the CPU time of the current thread. *)valget_thread_clock:(unit->t)Or_error.tend(** {2 Eventfd functions} *)moduleEventfd:sigmoduleFlags:sigtypet=privateInt63.t[@@derivingsexp_of]includeFlags.Swithtypet:=tvalcloexec:t(** [EFD_CLOEXEC] *)valnonblock:t(** [EFD_NONBLOCK] *)valsemaphore:t(** [EFD_SEMAPHORE] *)endtypet=privateFile_descr.t[@@derivingcompare,sexp_of](** [create ?flags init] creates a new event file descriptor with [init] as the
counter's initial value. With Linux 2.6.26 or earlier, [flags] must be
[empty]. *)valcreate:(?flags:Flags.t->Int32.t->t)Or_error.t(** [read t] will block until [t]'s counter is nonzero, after which its behavior
depends on whether [t] was created with the {!Flags.semaphore} flag set. If it was
set, then [read t] will return [1] and decrement [t]'s counter. If it was not set,
then [read t] will return the value of [t]'s counter and set the counter to [0].
The returned value should be interpreted as an unsigned 64-bit integer.
In the case that [t] was created with the {!Flags.nonblock} flag set, this
function will raise a Unix error with the error code [EAGAIN] or [EWOULDBLOCK],
instead of blocking. *)valread:t->Int64.t(** [write t v] will block until [t]'s counter is less than the max value of a
[uint64_t], after which it will increment [t]'s counter by [v], which will be
interpreted as an unsigned 64-bit integer.
In the case that [t] was created with the {!Flags.nonblock} flag set, this
function will raise a Unix error with the error code [EAGAIN] or [EWOULDBLOCK],
instead of blocking. *)valwrite:t->Int64.t->unitvalto_file_descr:t->File_descr.tend(** {2 Timerfd functions} *)moduleTimerfd:sig(** Clock used to mark the progress of a timer. *)moduleClock:sigtypet[@@derivingbin_io,compare,sexp](** Settable system-wide clock. *)valrealtime:t(** Nonsettable clock. It is not affected by manual changes to the system time. *)valmonotonic:tendmoduleFlags:sigtypet[@@derivingsexp_of]includeFlags.Swithtypet:=tvalnonblock:t(** [TFD_NONBLOCK] *)valcloexec:t(** [TFD_CLOEXEC] *)endtypet=privateFile_descr.t[@@derivingbin_io,compare,sexp]valto_file_descr:t->File_descr.t(** [create ?flags clock] creates a new timer file descriptor. With Linux 2.6.26 or
earlier, [flags] must be empty. *)valcreate:(?flags:Flags.t->Clock.t->t)Or_error.t(** [set_at t at] and [set_after t span] set [t] to fire once, at [at] or after
[span]. [set_after] treats [span <= 0] as [span = 1ns]; unlike the underlying
system call, [timerfd_settime], it does not clear the timer if [span = 0]. To
clear a timerfd, use [Timerfd.clear].
[set_repeating ?after t interval] sets [t] to fire every [interval] starting after
[after] (default is [interval]), raising if [interval <= 0]. *)valset_at:t->Time_ns.t->unitvalset_after:t->Time_ns.Span.t->unitvalset_repeating:?after:Time_ns.Span.t->t->Time_ns.Span.t->unit(** [clear t] causes [t] to not fire anymore. *)valclear:t->unittyperepeat={fire_after:Time_ns.Span.t;interval:Time_ns.Span.t}(** [get t] returns the current state of the timer [t]. *)valget:t->[`Not_armed|`Fire_afterofTime_ns.Span.t|`Repeatofrepeat](**/**)(*_ See the Jane Street Style Guide for an explanation of [Private] submodules:
https://opensource.janestreet.com/standards/#private-submodules *)modulePrivate:sigvalunsafe_timerfd_settime:File_descr.t->bool->initial:Int63.t->interval:Int63.t->Syscall_result.Unit.tendend(** {2 Parent death notifications} *)(** [pr_set_pdeathsig s] sets the signal [s] to be sent to the executing process when
its parent dies. NOTE: the parent may have died before or while executing this
system call. To make sure that you do not miss this event, you should call
{!getppid} to get the parent process id after this system call. If the parent has
died, the returned parent PID will be 1, i.e., the init process will have adopted
the child. You should then either send the signal to yourself using [Unix.kill], or
execute an appropriate handler. *)valpr_set_pdeathsig:(Signal.t->unit)Or_error.t(** [pr_get_pdeathsig ()] gets the signal that will be sent to the currently executing
process when its parent dies. *)valpr_get_pdeathsig:(unit->Signal.t)Or_error.t(** {2 Task name} *)(** [pr_set_name_first16 name] sets the name of the executing thread to [name]. Only
the first 16 bytes in [name] will be used; the rest is ignored. *)valpr_set_name_first16:(string->unit)Or_error.t(** [pr_get_name ()] gets the name of the executing thread. The name is at most 16
bytes long. *)valpr_get_name:(unit->string)Or_error.t(** {2 Pathname resolution} *)(** [file_descr_realpath fd] returns the canonicalized absolute pathname of the file
associated with file descriptor [fd].
Raises [Unix_error] on errors. *)valfile_descr_realpath:(File_descr.t->string)Or_error.t(** [out_channel_realpath oc] returns the canonicalized absolute pathname of the file
associated with output channel [oc].
Raises [Unix_error] on errors. *)valout_channel_realpath:(Out_channel.t->string)Or_error.t(** [in_channel_realpath ic] returns the canonicalized absolute pathname of the file
associated with input channel [ic].
Raises [Unix_error] on errors.
*)valin_channel_realpath:(In_channel.t->string)Or_error.t(** {2 Affinity} *)(** Setting the CPU affinity causes a process to only run on the cores chosen. You can
find out how many cores a system has in /proc/cpuinfo. This can be useful in two
ways: first, it limits a process to a core so that it won't interfere with processes
on other cores. Second, you save time by not moving the process back and forth
between CPUs, which sometimes invalidates their cache. See [man sched_setaffinity]
for details. *)valsched_setaffinity:(?pid:Pid.t->cpuset:intlist->unit->unit)Or_error.tvalsched_getaffinity:(?pid:Pid.t->unit->intlist)Or_error.tvalsched_setaffinity_this_thread:(cpuset:intlist->unit)Or_error.t(** [cores ()] returns the number of cores on the machine. This may be different
than the number of cores available to the calling process. *)valcores:(unit->int)Or_error.t(** [get_terminal_size term] returns [(rows, cols)], the number of rows and columns of
the controlling terminal (raises if no controlling terminal), or of the specified
file descriptor (useful when writing to stdout, because stdout doesn't have to be
the controlling terminal). *)valget_terminal_size:([`Controlling|`FdofFile_descr.t]->int*int)Or_error.t(** [Priority.t] is what is usually referred to as the "nice" value of a process. It is
also known as the "dynamic" priority. It is used with normal (as opposed to
real-time) processes that have static priority zero. See [Unix.Scheduler.set] for
setting the static priority. *)modulePriority:sigtypet[@@derivingsexp]valequal:t->t->boolvalof_int:int->tvalto_int:t->intvalincr:t->tvaldecr:t->tend(** Set the calling thread's priority in the Linux scheduler *)valsetpriority:(Priority.t->unit)Or_error.t(** Get the calling thread's priority in the Linux scheduler *)valgetpriority:(unit->Priority.t)Or_error.t(** [get_ipv4_address_for_interface "eth0"] returns the IP address assigned to eth0, or
throws an exception if no IP address is configured. *)valget_ipv4_address_for_interface:(string->string)Or_error.t(** [bind_to_interface fd (Only "eth0")] restricts packets from being
received/sent on the given file descriptor [fd] on any interface other than "eth0".
Use [bind_to_interface fd Any] to allow traffic on any interface. The bindings are
not cumulative; you may only select one interface, or [Any].
Not to be confused with a traditional BSD sockets API [bind()] call, this
Linux-specific socket option ([SO_BINDTODEVICE]) is used for applications on
multi-homed machines with specific security concerns. For similar functionality
when using multicast, see {!Core_unix.mcast_set_ifname}. *)valbind_to_interface:(File_descr.t->Bound_to_interface.t->unit)Or_error.t(** [get_bind_to_interface fd] returns the current interface the socket is bound to. It
uses getsockopt() with Linux-specific [SO_BINDTODEVICE] option. Empty string means
it is not bound to any specific interface. See [man 7 socket] for more information.
*)valget_bind_to_interface:(File_descr.t->Bound_to_interface.t)Or_error.t(** epoll(): a Linux I/O multiplexer of the same family as select() or poll(). Its main
differences are support for Edge- or Level-triggered notifications (we're using
Level-triggered to emulate "select") and much better scaling with the number of file
descriptors.
See the man pages for a full description of the epoll facility. *)moduleEpoll:sigmoduleFlags:sig(** An [Epoll.Flags.t] is an immutable set of flags for which one can register
interest in a file descriptor. It is implemented as a bitmask, and so all
operations (+, -, etc.) are constant time with no allocation.
[sexp_of_t] produces a human-readable list of bits, e.g., "(in out)". *)typet[@@derivingsexp_of]includeFlags.Swithtypet:=t(** The names of the flags match the man pages. E.g. [in_] = "EPOLLIN", [out] =
"EPOLLOUT", etc. *)valnone:t(** Associated fd is readable *)valin_:t(** Associated fd is readable *)valout:t(** Associated fd is writable *)(*_ val rdhup : t (\* Event flag For detecting tcp half-close *\) *)valpri:t(** Urgent data available *)valerr:t(** Error condition (always on, no need to set it) *)valhup:t(** Hang up happened (always on) *)valet:t(** Edge-Triggered behavior (see man page) *)valoneshot:t(** One-shot behavior for the associated fd *)end(** An [Epoll.t] maintains a map from [File_descr.t] to [Flags.t], where the domain is
the set of file descriptors that one is interested in, and the flags associated
with each file descriptor specify the types of events one is interested in being
notified about for that file descriptor. Our implementation maintains a
user-level table equivalent to the kernel epoll set, so that [sexp_of_t] produces
useful human-readable information, and so that we can present our standard table
interface.
The implementation assumes that one never closes a file descriptor that is the
domain of an [Epoll.t], since doing so might remove the [fd] from the kernel epoll
set without the implementation's knowledge.
An [Epoll.t] also has a buffer that is used to store the set of ready [fd]s
returned by calling [wait]. *)typet[@@derivingsexp_of]valinvariant:t->unit(** [create ~num_file_descrs] creates a new epoll set able to watch file descriptors
in \[0, [num_file_descrs]). Additionally, the set allocates space for reading the
"ready" events when [wait] returns, allowing for up to [max_ready_events] to be
returned in a single call to [wait]. *)valcreate:(num_file_descrs:int->max_ready_events:int->t)Or_error.tvalclose:t->unit(** Map operations *)(** [find] raises in the case that [t] is closed. *)valfind:t->File_descr.t->Flags.toptionvalfind_exn:t->File_descr.t->Flags.tvalset:t->File_descr.t->Flags.t->unitvalremove:t->File_descr.t->unitvaliter:t->f:(File_descr.t->Flags.t->unit)->unit(** [wait t ~timeout] blocks until at least one file descriptor in [t] is ready for
one of the events it is being watched for, or [timeout] passes. [wait] side
effects [t] by storing the ready set in it. One can subsequently access the ready
set by calling [iter_ready] or [fold_ready].
With [wait ~timeout:(`After span)], [span <= 0] is treated as [0]. If [span > 0],
then [span] is rounded to the nearest millisecond, with a minimum value of one
millisecond.
Note that this method should not be considered thread-safe. There is mutable
state in [t] that will be changed by invocations to [wait] that cannot be
prevented by mutexes around [wait]. *)valwait:t->timeout:[`Never|`Immediately|`AfterofTime_ns.Span.t]->[`Ok|`Timeout](** [wait_timeout_after t span = wait t ~timeout:(`After span)]. [wait_timeout_after]
is a performance hack to avoid allocating [`After span]. *)valwait_timeout_after:t->Time_ns.Span.t->[`Ok|`Timeout](** [iter_ready] and [fold_ready] iterate over the ready set computed by the last
call to [wait]. *)valiter_ready:t->f:(File_descr.t->Flags.t->unit)->unitvalfold_ready:t->init:'a->f:('a->File_descr.t->Flags.t->'a)->'a(*_
(* pwait -> with the specified sigmask, analogous to pselect *)
(* val pwait : t -> timeout:Span.t -> int list -> [ `Ok of Ready_fds.t | `Timeout ] *)
*)endmoduleExtended_file_attributes:sig(** Extended attributes are name:value pairs associated with inodes (files,
directories, symlinks, etc). They are extensions to the normal attributes which
are associated with all inodes in the system (i.e. the 'man 2 stat' data). A
complete overview of extended attributes concepts can be found in 'man 5 attr'.
[getxattr] retrieves the value of the extended attribute identified by name and
associated with the given path in the filesystem.
The [name] includes a namespace prefix - there may be several, disjoint namespaces
associated with an individual inode. The [value] is a chunk of arbitrary textual
or binary data.
If the attribute exists, it is returned as [Ok string]. Several common errors are
returned as possible constructors, namely:
- [ENOATTR]: The named attribute does not exist, or the process has no access to
this attribute.
- [ERANGE]: The size of the value buffer is too small to hold the result.
- [ENOTSUP]: Extended attributes are not supported by the filesystem, or are
disabled.
Many other errors are possible, and will raise an exception. See the man pages for
full details. *)moduleGet_attr_result:sigtypet=|Okofstring|ENOATTR|ERANGE|ENOTSUP[@@derivingsexp_of]endvalgetxattr:(path:string->name:string->Get_attr_result.t)Or_error.t(** [setxattr] sets the value of the extended attribute identified by name and
associated with the given path in the filesystem.
[how] defaults to [`Set], in which case the extended attribute will be created if
need be, or will simply replace the value if the attribute exists. If [how] is
[`Create], then [setxattr] returns [EEXIST] if the named attribute exists already.
If [how] is [`Replace], then [setxattr] returns [ENOATTR] if the named attribute
does not already exist.
[ENOTSUP] means extended attributes are not supported by the filesystem, or are
disabled. Many other errors are possible, and will raise an exception. See the man
pages for full details. *)moduleSet_attr_result:sigtypet=|Ok|EEXIST|ENOATTR|ENOTSUP[@@derivingsexp_of]endvalsetxattr:(?how:[`Set|`Create|`Replace]->path:string->name:string->value:string->unit->Set_attr_result.t)Or_error.tendend