module UnixLabels:sig
..end
与 Unix 系统的接口。
要使用此模块的带标签版本,请在您的实现中添加 module Unix
=
UnixLabels
。
注意:此模块的所有函数(除了 UnixLabels.error_message
和 UnixLabels.handle_unix_error
)都可能在底层系统调用发出错误信号时引发 UnixLabels.Unix_error
异常。
typeerror =
Unix.error
=
| |
E2BIG |
(* | 参数列表过长 | *) |
| |
EACCES |
(* | 权限被拒绝 | *) |
| |
EAGAIN |
(* | 资源暂时不可用;请重试 | *) |
| |
EBADF |
(* | 错误的文件描述符 | *) |
| |
EBUSY |
(* | 资源不可用 | *) |
| |
ECHILD |
(* | 没有子进程 | *) |
| |
EDEADLK |
(* | 资源死锁将发生 | *) |
| |
EDOM |
(* | 数学函数等域错误。 | *) |
| |
EEXIST |
(* | 文件存在 | *) |
| |
EFAULT |
(* | 错误地址 | *) |
| |
EFBIG |
(* | 文件太大 | *) |
| |
EINTR |
(* | 函数被信号中断 | *) |
| |
EINVAL |
(* | 无效参数 | *) |
| |
EIO |
(* | 硬件 I/O 错误 | *) |
| |
EISDIR |
(* | 是一个目录 | *) |
| |
EMFILE |
(* | 进程打开的文件太多 | *) |
| |
EMLINK |
(* | 链接太多 | *) |
| |
ENAMETOOLONG |
(* | 文件名太长 | *) |
| |
ENFILE |
(* | 系统中打开的文件太多 | *) |
| |
ENODEV |
(* | 没有这样的设备 | *) |
| |
ENOENT |
(* | 没有这样的文件或目录 | *) |
| |
ENOEXEC |
(* | 不是可执行文件 | *) |
| |
ENOLCK |
(* | 没有可用的锁 | *) |
| |
ENOMEM |
(* | 内存不足 | *) |
| |
ENOSPC |
(* | 设备上没有剩余空间 | *) |
| |
ENOSYS |
(* | 不支持该函数 | *) |
| |
ENOTDIR |
(* | 不是目录 | *) |
| |
ENOTEMPTY |
(* | 目录不为空 | *) |
| |
ENOTTY |
(* | 不适当的 I/O 控制操作 | *) |
| |
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 |
(* | 未知错误 | *) |
错误代码的类型。POSIX 标准中定义的错误以及 UNIX98 和 BSD 中的附加错误。所有其他错误都映射到 EUNKNOWNERR。
exception Unix_error of error * string * string
在遇到错误时,由以下系统调用引发。第一个组件是错误代码;第二个组件是函数名称;第三个组件是函数的字符串参数(如果有),否则为空字符串。
UnixLabels.Unix_error
和 Unix.Unix_error
是相同的,捕获其中一个将捕获另一个。
val error_message : error -> string
返回描述给定错误代码的字符串。
val handle_unix_error : ('a -> 'b) -> 'a -> 'b
handle_unix_error f x
将 f
应用于 x
并返回结果。如果引发了异常 UnixLabels.Unix_error
,它将打印一条描述错误的消息并以代码 2 退出。
val environment : unit -> string array
返回进程环境,作为格式为 ``variable=value'' 的字符串数组。如果进程具有特殊权限,则返回的数组为空。
val unsafe_environment : unit -> string array
返回进程环境,作为格式为 ``variable=value'' 的字符串数组。与 UnixLabels.environment
不同,即使进程具有特殊权限,此函数也会返回一个填充的数组。有关更多详细信息,请参阅 UnixLabels.unsafe_getenv
的文档。
val getenv : string -> string
返回与进程环境中变量关联的值,除非进程具有特殊权限。
Not_found
,如果变量未绑定或进程具有特殊权限。此函数与 Sys.getenv
相同。val unsafe_getenv : string -> string
返回与进程环境中变量关联的值。
与 UnixLabels.getenv
不同,即使进程具有特殊权限,此函数也会返回该值。它被认为是不安全的,因为设置 UID 或设置 GID 程序的程序员必须注意避免在可执行文件的搜索路径、临时文件或日志的位置等地方使用恶意制作的环境变量。
Not_found
,如果变量未绑定。val putenv : string -> string -> unit
putenv name value
设置与进程环境中变量关联的值。 name
是环境变量的名称,value
是其新的关联值。
typeprocess_status =
Unix.process_status
=
| |
WEXITED of |
(* | 进程通过 | *) |
| |
WSIGNALED of |
(* | 进程被信号杀死;参数是信号编号。 | *) |
| |
WSTOPPED of |
(* | 进程被信号停止;参数是信号编号。 | *) |
进程的终止状态。有关标准信号编号的定义,请参阅模块 Sys
。请注意,它们不是操作系统使用的编号。
在 Windows 上:仅使用 WEXITED
(因为没有进程间信号),但使用特定的返回值来指示特殊的终止原因。在 Windows 文档中查找 NTSTATUS
值以解码此类错误返回值。特别是,STATUS_ACCESS_VIOLATION
错误代码是 32 位 0xC0000005
:由于 Int32.of_int 0xC0000005
是 -1073741819
,因此 WEXITED -1073741819
等效于 Windows 上的 WSIGNALED Sys.sigsegv
。
typewait_flag =
Unix.wait_flag
=
| |
WNOHANG |
(* | 如果还没有子进程死亡,则不要阻塞,而是立即返回 pid 等于 0。 | *) |
| |
WUNTRACED |
(* | 还报告接收停止信号的子进程。 | *) |
用于 UnixLabels.waitpid
的标志。
val execv : prog:string -> args:string array -> 'a
execv prog args
使用参数 args
和当前进程环境执行文件 prog
中的程序。请注意,第一个参数 args.(0)
通常是正在执行的程序的文件名,就像 Sys.argv.(0)
一样。这些 execv*
函数永远不会返回:如果成功,当前程序将被新程序替换。
在 Windows 上:CRT 只会生成一个新进程并退出当前进程。如果例如另一个进程正在等待当前进程,这将产生不想要的结果。建议改为使用 UnixLabels.create_process
或其中一个 open_process_*
函数。
Unix_error
val execve : prog:string -> args:string array -> env:string array -> 'a
与 UnixLabels.execv
相同,但第三个参数提供给执行程序的环境。
val execvp : prog:string -> args:string array -> 'a
与 UnixLabels.execv
相同,但程序在路径中搜索。
val execvpe : prog:string -> args:string array -> env:string array -> 'a
与 UnixLabels.execve
相同,但程序在路径中搜索。
val fork : unit -> int
派生一个新进程。返回的整数对于子进程为 0,对于父进程为子进程的 pid。如果 OCaml 进程是多核的(任何域已被派生),则它将失败。此外,如果已派生 Thread 模块中的任何线程,则子进程可能处于损坏状态。
Invalid_argument
。请改用 UnixLabels.create_process
或线程。Failure
。val wait : unit -> int * process_status
等待直到一个子进程死亡,并返回其 pid 和终止状态。
Invalid_argument
。请改用 UnixLabels.waitpid
。val waitpid : mode:wait_flag list -> int -> int * process_status
与 UnixLabels.wait
相同,但等待给定 pid 的子进程。pid 为 -1
表示等待任何子进程。pid 为 0
表示等待与当前进程位于同一进程组中的任何子进程。负 pid 参数表示进程组。选项列表指示 waitpid
是否应该立即返回而不等待,以及它是否应该报告已停止的子进程。
在 Windows 上:只能等待给定 PID,而不是任何子进程。
val system : string -> process_status
执行给定的命令,等待直到它终止,并返回其终止状态。字符串由 shell /bin/sh
(或 Windows 上的命令解释器 cmd.exe
)解释,因此可以包含重定向、引号、变量等。为了正确引用文件名或命令参数中出现的空格和 shell 特殊字符,建议使用 Filename.quote_command
。结果 WEXITED 127
表示 shell 无法执行。
val _exit : int -> 'a
立即终止调用进程,将给定的状态码返回给操作系统:通常为 0 表示没有错误,小正整数表示失败。与 exit
不同,Unix._exit
不会执行任何最终化操作:使用 at_exit
注册的函数不会被调用,输入/输出通道不会被刷新,C 运行时系统也不会被最终化。
Unix._exit
的典型用法是在 Unix.fork
操作之后,当子进程遇到致命错误并必须退出时。在这种情况下,最好不要在子进程中执行任何最终化操作,因为这些操作可能会干扰父进程执行的类似操作。例如,子进程不应刷新输出通道,因为父进程以后可能会再次刷新它们,从而导致重复输出。
val getpid : unit -> int
返回进程的 pid。
val getppid : unit -> int
返回父进程的 pid。
Invalid_argument
(因为它没有意义)val nice : int -> int
更改进程优先级。整数参数将添加到“nice”值中。(“nice”值越高表示优先级越低。)返回新的 nice 值。
Invalid_argument
typefile_descr =
Unix.file_descr
文件描述符的抽象类型。
val stdin : file_descr
标准输入的文件描述符。
val stdout : file_descr
标准输出的文件描述符。
val stderr : file_descr
标准错误的文件描述符。
typeopen_flag =
Unix.open_flag
=
| |
O_RDONLY |
(* | 以只读方式打开 | *) |
| |
O_WRONLY |
(* | 以只写方式打开 | *) |
| |
O_RDWR |
(* | 以读写方式打开 | *) |
| |
O_NONBLOCK |
(* | 以非阻塞模式打开 | *) |
| |
O_APPEND |
(* | 以追加方式打开 | *) |
| |
O_CREAT |
(* | 如果不存在则创建 | *) |
| |
O_TRUNC |
(* | 如果存在则截断为 0 长度 | *) |
| |
O_EXCL |
(* | 如果存在则失败 | *) |
| |
O_NOCTTY |
(* | 不要将此设备设为控制 tty | *) |
| |
O_DSYNC |
(* | 写入完成为“同步 I/O 数据完整性完成” | *) |
| |
O_SYNC |
(* | 写入完成为“同步 I/O 文件完整性完成” | *) |
| |
O_RSYNC |
(* | 读取完成为写入(取决于 O_SYNC/O_DSYNC) | *) |
| |
O_SHARE_DELETE |
(* | 仅 Windows:允许在仍然打开时删除文件 | *) |
| |
O_CLOEXEC |
(* | 在由 | *) |
| |
O_KEEPEXEC |
(* | 清除 close-on-exec 标志。目前,这是默认设置。 | *) |
对 UnixLabels.openfile
的标志。
typefile_perm =
int
文件访问权限类型,例如 0o640
表示用户可读写、组可读、其他不可访问
val openfile : string ->
mode:open_flag list ->
perm:file_perm -> file_descr
使用给定的标志打开命名文件。第三个参数是如果创建文件要赋予的权限(请参见 UnixLabels.umask
)。返回命名文件的描述符。
val close : file_descr -> unit
关闭文件描述符。
val fsync : file_descr -> unit
将文件缓冲区刷新到磁盘。
val read : file_descr -> buf:bytes -> pos:int -> len:int -> int
read fd ~buf ~pos ~len
从描述符 fd
中读取 len
个字节,将它们存储在字节序列 buf
中,从 buf
中的 pos
位置开始。返回实际读取的字节数。
val read_bigarray : file_descr ->
buf:('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray.Array1.t ->
pos:int -> len:int -> int
与 UnixLabels.read
相同,但将数据读入 bigarray 中。
val write : file_descr -> buf:bytes -> pos:int -> len:int -> int
write fd ~buf ~pos ~len
将 len
个字节写入描述符 fd
,从字节序列 buf
中获取它们,从 buff
中的 pos
位置开始。返回实际写入的字节数。 write
重复写入操作,直到所有字节都已写入或发生错误。
val write_bigarray : file_descr ->
buf:('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray.Array1.t ->
pos:int -> len:int -> int
与 UnixLabels.write
相同,但从 bigarray 中获取数据。
val single_write : file_descr -> buf:bytes -> pos:int -> len:int -> int
与 UnixLabels.write
相同,但尝试只写入一次。因此,如果发生错误,则 single_write
保证没有数据被写入。
val write_substring : file_descr -> buf:string -> pos:int -> len:int -> int
与 UnixLabels.write
相同,但从字符串而不是字节序列中获取数据。
val single_write_substring : file_descr -> buf:string -> pos:int -> len:int -> int
与 UnixLabels.single_write
相同,但从字符串而不是字节序列中获取数据。
val single_write_bigarray : file_descr ->
buf:('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray.Array1.t ->
pos:int -> len:int -> int
与 UnixLabels.single_write
相同,但从 bigarray 中获取数据。
val in_channel_of_descr : file_descr -> in_channel
创建一个从给定描述符中读取的输入通道。该通道最初处于二进制模式;如果需要文本模式,请使用 set_binary_mode_in ic false
。仅当描述符引用文件或管道时才支持文本模式,但如果它引用套接字,则不支持。
在 Windows 上:set_binary_mode_in
在使用此函数创建的通道上始终失败。
请注意,输入通道是缓冲的,因此可能从描述符中读取了比使用通道函数访问的字符更多的字符。通道还保留文件当前位置的副本。
使用 close_in ic
关闭由 in_channel_of_descr fd
返回的通道 ic
也会关闭底层描述符 fd
。关闭通道 ic
和描述符 fd
两者是不正确的。
如果在同一个描述符上创建了多个通道,则必须关闭其中一个通道,而不能关闭其他通道。例如,考虑与套接字连接的描述符 s
和两个通道 ic = in_channel_of_descr s
和 oc = out_channel_of_descr s
。建议的关闭协议是执行 close_out oc
,它将缓冲的输出刷新到套接字,然后关闭套接字。ic
通道不能关闭,并且最终将由 GC 收集。
val out_channel_of_descr : file_descr -> out_channel
创建一个在给定描述符上写入的输出通道。该通道最初处于二进制模式;如果需要文本模式,请使用 set_binary_mode_out oc false
。仅当描述符引用文件或管道时才支持文本模式,但如果它引用套接字,则不支持。
在 Windows 上:set_binary_mode_out
在使用此函数创建的通道上始终失败。
请注意,输出通道是缓冲的,因此您可能需要调用 flush
以确保所有数据都已发送到描述符。通道还保留文件当前位置的副本。
使用 close_out oc
关闭由 out_channel_of_descr fd
返回的通道 oc
也会关闭底层描述符 fd
。关闭通道 ic
和描述符 fd
两者是不正确的。
请参见 Unix.in_channel_of_descr
,了解在同一个描述符上创建了多个通道时的关闭协议。
val descr_of_in_channel : in_channel -> file_descr
返回与输入通道对应的描述符。
val descr_of_out_channel : out_channel -> file_descr
返回与输出通道对应的描述符。
typeseek_command =
Unix.seek_command
=
| |
SEEK_SET |
(* | 表示相对于文件开头的定位 | *) |
| |
SEEK_CUR |
(* | 表示相对于当前位置的定位 | *) |
| |
SEEK_END |
(* | 表示相对于文件末尾的定位 | *) |
对 UnixLabels.lseek
的定位模式。
val lseek : file_descr -> int -> mode:seek_command -> int
设置文件描述符的当前位置,并返回结果偏移量(相对于文件开头)。
val truncate : string -> len:int -> unit
将命名文件截断为给定大小。
val ftruncate : file_descr -> len:int -> unit
将对应于给定描述符的文件截断为给定大小。
typefile_kind =
Unix.file_kind
=
| |
S_REG |
(* | 普通文件 | *) |
| |
S_DIR |
(* | 目录 | *) |
| |
S_CHR |
(* | 字符设备 | *) |
| |
S_BLK |
(* | 块设备 | *) |
| |
S_LNK |
(* | 符号链接 | *) |
| |
S_FIFO |
(* | 命名管道 | *) |
| |
S_SOCK |
(* | 套接字 | *) |
typestats =
Unix.stats
= {
|
st_dev : |
(* | 设备号 | *) |
|
st_ino : |
(* | 节点号 | *) |
|
st_kind : |
(* | 文件类型 | *) |
|
st_perm : |
(* | 访问权限 | *) |
|
st_nlink : |
(* | 链接数 | *) |
|
st_uid : |
(* | 所有者用户 ID | *) |
|
st_gid : |
(* | 文件所属组的组 ID | *) |
|
st_rdev : |
(* | 设备 ID(如果是特殊文件) | *) |
|
st_size : |
(* | 大小(字节) | *) |
|
st_atime : |
(* | 最后访问时间 | *) |
|
st_mtime : |
(* | 最后修改时间 | *) |
|
st_ctime : |
(* | 最后状态更改时间 | *) |
}
由 UnixLabels.stat
调用返回的信息。
val stat : string -> stats
返回指定文件的相关信息。
val lstat : string -> stats
与 UnixLabels.stat
相同,但如果文件是符号链接,则返回链接本身的信息。
val fstat : file_descr -> stats
返回与给定描述符关联的文件的相关信息。
val isatty : file_descr -> bool
如果给定文件描述符指向终端或控制台窗口,则返回 true
,否则返回 false
。
module LargeFile:sig
..end
大型文件上的文件操作。
val map_file : file_descr ->
?pos:int64 ->
kind:('a, 'b) Bigarray.kind ->
layout:'c Bigarray.layout ->
shared:bool -> dims:int array -> ('a, 'b, 'c) Bigarray.Genarray.t
将文件作为 Bigarray 映射到内存。 map_file fd ~kind ~layout ~shared ~dims
返回一个类型为 kind
,布局为 layout
,维度如 dims
所指定的 Bigarray。此 Bigarray 中包含的数据是文件描述符 fd
所引用的文件的内容(例如,之前使用 UnixLabels.openfile
打开)。可选的 pos
参数是在要映射的数据中文件中的字节偏移量;默认值为 0(从文件开头映射)。
如果 shared
为 true
,则对数组执行的所有修改都反映在文件中。这需要 fd
以写入权限打开。如果 shared
为 false
,则对数组执行的修改仅在内存中完成,使用修改页面的写时复制;基础文件不受影响。
UnixLabels.map_file
比将整个文件读入 Bigarray、修改该 Bigarray 然后写入更有效。
为了自动调整 Bigarray 的维度以适应文件的实际大小,主维度(即,对于使用 C 布局的数组,是第一个维度,而对于使用 Fortran 布局的数组,是最后一个维度)可以指定为 -1
。然后,UnixLabels.map_file
会根据文件的大小确定主维度。文件必须包含根据非主维度确定的整数个子数组,否则会引发 Failure
。
如果指定了 Bigarray 的所有维度,则会将文件大小与 Bigarray 的大小进行匹配。如果文件大于 Bigarray,则只有文件的初始部分被映射到 Bigarray。如果文件小于 Bigarray,则文件会自动扩展到 Bigarray 的大小。这需要对 fd
具有写入权限。
对数组的访问会进行边界检查,但边界由对 map_file
的初始调用确定。因此,您应该确保在访问映射文件时,没有其他进程修改映射文件,否则可能会引发 SIGBUS 信号。例如,当文件缩小时会发生这种情况。
如果参数验证失败,可能会引发 Invalid_argument
或 Failure
。
val unlink : string -> unit
删除指定文件。
如果指定文件是目录,则会引发
EPERM
在符合 POSIX 标准的系统上EISDIR
在 Linux >= 2.1.132 上EACCESS
在 Windows 上val rename : src:string -> dst:string -> unit
rename ~src ~dst
将文件的名称从 src
更改为 dst
,根据需要在目录之间移动。如果 dst
已经存在,则其内容将被 src
的内容替换。根据操作系统的不同,dst
的元数据(权限、所有者等)可以保留或被 src
的元数据替换。
val link : ?follow:bool -> src:string -> dst:string -> unit
link ?follow ~src ~dst
为名为 src
的文件创建一个名为 dst
的硬链接。
ENOSYS
在 Unix 上,如果请求了 ~follow:_
,但 linkat 不可用。ENOSYS
在 Windows 上,如果请求了 ~follow:false
。follow
:指示是遵循 src
符号链接,还是创建指向 src
本身的硬链接。在 Unix 系统上,这是使用 linkat(2)
函数完成的。如果未提供 ?follow
,则使用 link(2)
函数,其行为是操作系统相关的,但更广泛地可用。val realpath : string -> string
realpath p
是 p
的绝对路径名,它是通过解析所有额外的 /
字符、相对路径段和符号链接获得的。
typeaccess_permission =
Unix.access_permission
=
| |
R_OK |
(* | 读取权限 | *) |
| |
W_OK |
(* | 写入权限 | *) |
| |
X_OK |
(* | 执行权限 | *) |
| |
F_OK |
(* | 文件存在 | *) |
UnixLabels.access
调用的标志。
val chmod : string -> perm:file_perm -> unit
更改指定文件的权限。
val fchmod : file_descr -> perm:file_perm -> unit
更改已打开文件的权限。
Invalid_argument
val chown : string -> uid:int -> gid:int -> unit
更改指定文件的拥有者 uid 和拥有者 gid。
Invalid_argument
val fchown : file_descr -> uid:int -> gid:int -> unit
更改已打开文件的拥有者 uid 和拥有者 gid。
Invalid_argument
val umask : file_perm -> file_perm
设置进程的文件模式创建掩码,并返回之前的掩码。
Invalid_argument
val access : string -> perm:access_permission list -> unit
检查进程是否对指定文件具有给定的权限。
在 Windows 上:无法测试执行权限 X_OK
,只测试读取权限。
Unix_error
,否则。val dup : ?cloexec:bool -> file_descr -> file_descr
返回一个新的文件描述符,它引用与给定描述符相同的文件。有关 cloexec
可选参数的文档,请参阅 UnixLabels.set_close_on_exec
。
val dup2 : ?cloexec:bool ->
src:file_descr -> dst:file_descr -> unit
dup2 ~src ~dst
将 src
复制到 dst
,如果 dst
已经打开,则关闭它。有关 cloexec
可选参数的文档,请参阅 UnixLabels.set_close_on_exec
。
val set_nonblock : file_descr -> unit
在给定描述符上设置“非阻塞”标志。当设置非阻塞标志时,在暂时没有可用数据的描述符上读取会导致引发 EAGAIN
或 EWOULDBLOCK
错误,而不是阻塞;在暂时没有写入空间的描述符上写入也会引发 EAGAIN
或 EWOULDBLOCK
。
val clear_nonblock : file_descr -> unit
清除给定描述符上的“非阻塞”标志。请参阅 UnixLabels.set_nonblock
。
val set_close_on_exec : file_descr -> unit
在给定描述符上设置“关闭-在-执行”标志。当当前进程使用 exec
、create_process
和 open_process
函数启动另一个程序时,带有关闭-在-执行标志的描述符会自动关闭。
将文件描述符(例如,在私有文件上打开的文件描述符)泄漏到外部程序通常是一个安全漏洞:然后,程序将获得对私有文件的访问权限,并可以使用它做一些不好的事情。因此,强烈建议将所有文件描述符设置为“关闭-在-执行”,除非在极少数情况下,文件描述符实际上需要传递到另一个程序。
将文件描述符设置为“关闭-在-执行”的最佳方法是在这种状态下创建它。为此,openfile
函数具有 O_CLOEXEC
和 O_KEEPEXEC
标志,分别用于强制执行“关闭-在-执行”模式或“保持-在-执行”模式。Unix 模块中创建文件描述符的所有其他操作都有一个可选参数 ?cloexec:bool
,用于指示是否应该在“关闭-在-执行”模式(通过写入 ~cloexec:true
)或“保持-在-执行”模式(通过写入 ~cloexec:false
)下创建文件描述符。出于历史原因,如果未给出 cloexec
可选参数,则默认文件描述符创建模式为“保持-在-执行”。这不是安全的默认值,因此强烈建议将显式的 cloexec
参数传递给创建文件描述符的操作。
cloexec
可选参数和 O_KEEPEXEC
标志是在 OCaml 4.05 中引入的。早些时候,常见的做法是在默认的“保持-在-执行”模式下创建文件描述符,然后在这些新创建的文件描述符上调用 set_close_on_exec
。这不如在“关闭-在-执行”模式下创建文件描述符安全,因为在多线程程序中,在创建文件描述符和 set_close_on_exec
完成之间存在漏洞窗口。如果另一个线程在此窗口期间生成另一个程序,则描述符将泄漏,因为它仍然处于“保持-在-执行”模式。
关于由 ~cloexec:true
或使用 O_CLOEXEC
标志提供的原子性保证:在所有平台上,都保证并发执行的 Caml 线程无法通过启动新进程泄漏描述符。在 Linux 上,此保证扩展到并发执行的 C 线程。截至 2017 年 2 月,其他操作系统缺乏必要的系统调用,并且仍然在 C 线程可以看到新创建的文件描述符处于“保持-在-执行”模式期间暴露漏洞窗口。
val clear_close_on_exec : file_descr -> unit
清除给定描述符上的“关闭-在-执行”标志。请参阅 UnixLabels.set_close_on_exec
。
val mkdir : string -> perm:file_perm -> unit
使用给定的权限创建目录(请参阅 UnixLabels.umask
)。
val rmdir : string -> unit
删除空目录。
val chdir : string -> unit
更改进程工作目录。
val getcwd : unit -> string
返回当前工作目录的名称。
val chroot : string -> unit
更改进程根目录。
Invalid_argument
typedir_handle =
Unix.dir_handle
打开目录上的描述符的类型。
val opendir : string -> dir_handle
在目录上打开描述符
val readdir : dir_handle -> string
返回目录中的下一个条目。
End_of_file
,当到达目录的末尾时。val rewinddir : dir_handle -> unit
将描述符重新定位到目录的开头
val closedir : dir_handle -> unit
关闭目录描述符。
val pipe : ?cloexec:bool -> unit -> file_descr * file_descr
创建管道。结果的第一部分是为读取打开的,即管道的出口。第二部分是为写入打开的,即管道的入口。有关 cloexec
可选参数的文档,请参阅 UnixLabels.set_close_on_exec
。
val mkfifo : string -> perm:file_perm -> unit
使用给定的权限创建一个命名管道(参见 UnixLabels.umask
)。
Invalid_argument
val create_process : prog:string ->
args:string array ->
stdin:file_descr ->
stdout:file_descr -> stderr:file_descr -> int
create_process ~prog ~args ~stdin ~stdout ~stderr
创建一个新的进程,该进程执行文件 prog
中的程序,参数为 args
。请注意,第一个参数 args.(0)
通常是正在执行的程序的文件名,就像 Sys.argv.(0)
一样。新进程的 pid 会立即返回;新进程与当前进程并发执行。新进程的标准输入和输出连接到描述符 stdin
、stdout
和 stderr
。例如,将 Unix.stdout
传递给 stdout
将阻止重定向,并使新进程与当前进程具有相同的标准输出。可执行文件 prog
在路径中进行搜索。新进程与当前进程具有相同的环境。
val create_process_env : prog:string ->
args:string array ->
env:string array ->
stdin:file_descr ->
stdout:file_descr -> stderr:file_descr -> int
create_process_env ~prog ~args ~env ~stdin ~stdout ~stderr
的工作原理与 UnixLabels.create_process
相同,只是额外的参数 env
指定了传递给程序的环境。
val open_process_in : string -> in_channel
高级管道和进程管理。此函数与程序并行运行给定的命令。命令的标准输出被重定向到管道,可以通过返回的输入通道读取。命令由 shell /bin/sh
(或 Windows 上的 cmd.exe
)解释,参见 UnixLabels.system
。函数 Filename.quote_command
可用于根据正在使用的 shell 对命令及其参数进行适当的引用。如果不需要通过 shell 运行命令,则可以使用 UnixLabels.open_process_args_in
作为 UnixLabels.open_process_in
的更健壮、更高效的替代方法。
val open_process_out : string -> out_channel
与 UnixLabels.open_process_in
相同,但将命令的标准输入重定向到管道。写入返回的输出通道的数据将发送到命令的标准输入。警告:对输出通道的写入会被缓冲,因此请务必在正确的时间调用 flush
以确保正确的同步。如果不需要通过 shell 运行命令,则可以使用 UnixLabels.open_process_args_out
而不是 UnixLabels.open_process_out
。
val open_process : string -> in_channel * out_channel
与 UnixLabels.open_process_out
相同,但将命令的标准输入和标准输出都重定向到连接到两个返回通道的管道。输入通道连接到命令的输出,输出通道连接到命令的输入。如果不需要通过 shell 运行命令,则可以使用 UnixLabels.open_process_args
而不是 UnixLabels.open_process
。
val open_process_full : string ->
env:string array ->
in_channel * out_channel * in_channel
类似于 UnixLabels.open_process
,但第二个参数指定了传递给命令的环境。结果是一个三元组通道,分别连接到命令的标准输出、标准输入和标准错误。如果不需要通过 shell 运行命令,则可以使用 UnixLabels.open_process_args_full
而不是 UnixLabels.open_process_full
。
val open_process_args : string -> string array -> in_channel * out_channel
open_process_args prog args
运行程序 prog
,参数为 args
。请注意,第一个参数 args.(0)
通常是正在执行的程序的文件名,就像 Sys.argv.(0)
一样。新进程与当前进程并发执行。新进程的标准输入和输出被重定向到管道,可以通过返回的通道分别进行读取和写入。输入通道连接到程序的输出,输出通道连接到程序的输入。
警告:对输出通道的写入会被缓冲,因此请务必在正确的时间调用 flush
以确保正确的同步。
在路径中搜索可执行文件 prog
。此行为在 4.12 中发生更改;之前 prog
仅在当前目录中查找。
新进程与当前进程具有相同的环境。
val open_process_args_in : string -> string array -> in_channel
与 UnixLabels.open_process_args
相同,但仅重定向新进程的标准输出。
val open_process_args_out : string -> string array -> out_channel
与 UnixLabels.open_process_args
相同,但仅重定向新进程的标准输入。
val open_process_args_full : string ->
string array ->
string array -> in_channel * out_channel * in_channel
类似于 UnixLabels.open_process_args
,但第三个参数指定了传递给新进程的环境。结果是一个三元组通道,分别连接到程序的标准输出、标准输入和标准错误。
val process_in_pid : in_channel -> int
返回通过 UnixLabels.open_process_args_in
打开的进程的 pid 或通过 UnixLabels.open_process_in
打开的 shell 的 pid。
val process_out_pid : out_channel -> int
返回通过 UnixLabels.open_process_args_out
打开的进程的 pid 或通过 UnixLabels.open_process_out
打开的 shell 的 pid。
val process_pid : in_channel * out_channel -> int
返回通过 UnixLabels.open_process_args
打开的进程的 pid 或通过 UnixLabels.open_process_args
打开的 shell 的 pid。
val process_full_pid : in_channel * out_channel * in_channel -> int
返回通过 UnixLabels.open_process_args_full
打开的进程的 pid 或通过 UnixLabels.open_process_full
打开的 shell 的 pid。
val close_process_in : in_channel -> process_status
关闭通过 UnixLabels.open_process_in
打开的通道,等待关联的命令终止,并返回其终止状态。
val close_process_out : out_channel -> process_status
关闭通过 UnixLabels.open_process_out
打开的通道,等待关联的命令终止,并返回其终止状态。
val close_process : in_channel * out_channel -> process_status
关闭通过 UnixLabels.open_process
打开的通道,等待关联的命令终止,并返回其终止状态。
val close_process_full : in_channel * out_channel * in_channel ->
process_status
关闭通过 UnixLabels.open_process_full
打开的通道,等待关联的命令终止,并返回其终止状态。
val symlink : ?to_dir:bool -> src:string -> dst:string -> unit
symlink ?to_dir ~src ~dst
将文件 dst
创建为指向文件 src
的符号链接。在 Windows 上,~to_dir
指示符号链接指向目录还是文件;如果省略,symlink
将使用 stat
检查 src
并相应地选择,如果 src
不存在,则假定为 false
(出于此原因,建议在新代码中指定 ~to_dir
参数)。在 Unix 上,~to_dir
被忽略。
Windows 符号链接在 Windows Vista 及更高版本中可用。Windows 符号链接与其 POSIX 对应物之间存在一些重要区别。
Windows 符号链接有两种类型:目录和常规,它们指定符号链接指向目录还是文件。类型必须正确 - 实际上指向文件的目录符号链接不能使用 chdir 选择,而实际上指向目录的文件符号链接不能读取或写入(请注意,Cygwin 的模拟层会忽略这种区别)。
当创建指向现有目标的符号链接时,这种区别并不重要,symlink
将自动创建正确类型的符号链接。当创建指向不存在的目标的符号链接时,这种区别就变得很重要。
另一个需要注意的是,默认情况下,符号链接是特权操作。管理员始终需要以提升的权限运行(或禁用 UAC),并且默认情况下,普通用户帐户需要通过本地安全策略 (secpol.msc) 或 Active Directory 授予 SeCreateSymbolicLinkPrivilege。
UnixLabels.has_symlink
可用于检查进程是否能够创建符号链接。
val has_symlink : unit -> bool
如果用户能够创建符号链接,则返回 true
。在 Windows 上,这表示用户不仅拥有 SeCreateSymbolicLinkPrivilege,而且还以提升的权限运行(如果需要)。在其他平台上,这仅表示 symlink 系统调用可用。
val readlink : string -> string
读取符号链接的内容。
val select : read:file_descr list ->
write:file_descr list ->
except:file_descr list ->
timeout:float ->
file_descr list * file_descr list *
file_descr list
等待某些通道上的某些输入/输出操作变得可能。这三个列表参数分别是:要检查读取的描述符集(第一个参数)、要检查写入的描述符集(第二个参数)或要检查异常条件的描述符集(第三个参数)。第四个参数是最大超时时间(以秒为单位);负的第四个参数表示没有超时(无限等待)。结果由三个描述符集组成:准备读取的描述符集(第一个组件)、准备写入的描述符集(第二个组件)以及挂起异常条件的描述符集(第三个组件)。
typelock_command =
Unix.lock_command
=
| |
F_ULOCK |
(* | 解锁一个区域 | *) |
| |
F_LOCK |
(* | 锁定一个区域以供写入,如果已被锁定则阻塞 | *) |
| |
F_TLOCK |
(* | 锁定一个区域以供写入,如果已被锁定则失败 | *) |
| |
F_TEST |
(* | 测试一个区域以查看其他进程的锁 | *) |
| |
F_RLOCK |
(* | 锁定一个区域以供读取,如果已被锁定则阻塞 | *) |
| |
F_TRLOCK |
(* | 锁定一个区域以供读取,如果已被锁定则失败 | *) |
UnixLabels.lockf
的命令。
val lockf : file_descr -> mode:lock_command -> len:int -> unit
lockf fd ~mode ~len
对作为 fd
打开的文件的一个区域进行锁定。该区域从 fd
的当前读/写位置(由 UnixLabels.lseek
设置)开始,如果 len
为正,则向前扩展 len
个字节,如果 len
为负,则向后扩展 len
个字节,如果 len
为零,则扩展到文件末尾。写锁阻止任何其他进程获取该区域的读锁或写锁。读锁阻止任何其他进程获取该区域的写锁,但允许其他进程获取该区域的读锁。
命令 F_LOCK
和 F_TLOCK
尝试对指定区域加写锁。 命令 F_RLOCK
和 F_TRLOCK
尝试对指定区域加读锁。 如果另一个进程加的锁阻止当前进程获取锁,F_LOCK
和 F_RLOCK
会阻塞,直到这些锁被移除,而 F_TLOCK
和 F_TRLOCK
会立即抛出异常并失败。 命令 F_ULOCK
会移除当前进程在指定区域加的任何锁。 最后,命令 F_TEST
会测试是否可以在指定区域加写锁,但不实际加锁。 如果成功,则立即返回;否则失败。
当一个进程尝试锁定已经被同一个进程锁定的文件区域时会发生什么取决于操作系统。 在 POSIX 兼容系统上,第二次锁定操作会成功,并可能将旧锁从读锁提升为写锁。 在 Windows 上,第二次锁定操作会阻塞或失败。
注意:信号处理程序的安装是通过函数 Sys.signal
和 Sys.set_signal
完成的。
val kill : pid:int -> signal:int -> unit
kill ~pid ~signal
向具有 ID 为 pid
的进程发送信号号为 signal
的信号。
在 Windows 上:只模拟了 Sys.sigkill
信号。
typesigprocmask_command =
Unix.sigprocmask_command
=
| |
SIG_SETMASK |
| |
SIG_BLOCK |
| |
SIG_UNBLOCK |
val sigprocmask : mode:sigprocmask_command -> int list -> int list
sigprocmask ~mode sigs
更改被阻塞信号集。 如果 mode
为 SIG_SETMASK
,则被阻塞信号被设置为列表 sigs
中的那些信号。 如果 mode
为 SIG_BLOCK
,则将 sigs
中的信号添加到被阻塞信号集中。 如果 mode
为 SIG_UNBLOCK
,则将 sigs
中的信号从被阻塞信号集中移除。 sigprocmask
返回先前被阻塞信号集。
当加载 Thread
模块的 systhreads 版本时,此函数会重定向到 Thread.sigmask
。 也就是说,sigprocmask
只改变当前线程的屏蔽。
Invalid_argument
(Windows 上没有进程间信号)val sigpending : unit -> int list
返回当前挂起的被阻塞信号集。
Invalid_argument
(Windows 上没有进程间信号)val sigsuspend : int list -> unit
sigsuspend sigs
原子地将被阻塞信号设置为 sigs
,并等待非忽略、非阻塞信号被传递。 返回时,被阻塞信号将重置为其初始值。
Invalid_argument
(Windows 上没有进程间信号)val pause : unit -> unit
等待非忽略、非阻塞信号被传递。
Invalid_argument
(Windows 上没有进程间信号)typeprocess_times =
Unix.process_times
= {
|
tms_utime : |
(* | 进程的用户时间 | *) |
|
tms_stime : |
(* | 进程的系统时间 | *) |
|
tms_cutime : |
(* | 子进程的用户时间 | *) |
|
tms_cstime : |
(* | 子进程的系统时间 | *) |
}
进程的执行时间(CPU 时间)。
typetm =
Unix.tm
= {
|
tm_sec : |
(* | 秒 0..60 | *) |
|
tm_min : |
(* | 分钟 0..59 | *) |
|
tm_hour : |
(* | 小时 0..23 | *) |
|
tm_mday : |
(* | 月中的日期 1..31 | *) |
|
tm_mon : |
(* | 年的月份 0..11 | *) |
|
tm_year : |
(* | 年份 - 1900 | *) |
|
tm_wday : |
(* | 星期几(星期日为 0) | *) |
|
tm_yday : |
(* | 年的日期 0..365 | *) |
|
tm_isdst : |
(* | 是否启用了夏令时 | *) |
}
表示墙上时钟时间和日历日期的类型。
val time : unit -> float
返回自 1970 年 1 月 1 日 00:00:00 GMT 以来的当前时间(以秒为单位)。
val gettimeofday : unit -> float
与 UnixLabels.time
相同,但分辨率优于 1 秒。
val gmtime : float -> tm
将时间(以秒为单位,由 UnixLabels.time
返回)转换为日期和时间。 假设为 UTC(协调世界时),也称为 GMT。 要执行逆转换,将 TZ 环境变量设置为“UTC”,使用 UnixLabels.mktime
,然后恢复 TZ 的原始值。
val localtime : float -> tm
将时间(以秒为单位,由 UnixLabels.time
返回)转换为日期和时间。 假设为本地时区。 执行逆转换的函数是 UnixLabels.mktime
。
val mktime : tm -> float * tm
将由 tm
参数指定的日期和时间转换为时间(以秒为单位,由 UnixLabels.time
返回)。 tm
的 tm_isdst
、tm_wday
和 tm_yday
字段被忽略。 还会返回给定 tm
记录的规范化副本,其中 tm_wday
、tm_yday
和 tm_isdst
字段已从其他字段重新计算,其他字段已规范化(因此,例如,10 月 40 日将更改为 11 月 9 日)。 tm
参数被解释为本地时区。
val alarm : int -> int
在给定的秒数之后安排 SIGALRM
信号。
Invalid_argument
val sleep : int -> unit
停止执行给定的秒数。
val sleepf : float -> unit
停止执行给定的秒数。 与 sleep
相同,但支持秒的几分之一。
val times : unit -> process_times
返回进程的执行时间。
在 Windows 上:部分实现,不会报告子进程的计时。
val utimes : string -> access:float -> modif:float -> unit
设置文件的最后访问时间(第二个参数)和最后修改时间(第三个参数)。 时间以自 1970 年 1 月 1 日 00:00:00 GMT 以来的秒数表示。 如果两个时间都为 0.0
,则访问时间和最后修改时间都将设置为当前时间。
typeinterval_timer =
Unix.interval_timer
=
| |
ITIMER_REAL |
(* | 在实际时间中递减,并在到期时发送信号 | *) |
| |
ITIMER_VIRTUAL |
(* | 在进程虚拟时间中递减,并在到期时发送 | *) |
| |
ITIMER_PROF |
(* | (用于分析)在进程运行时和系统代表进程运行时都递减;在到期时发送 | *) |
三种间隔计时器。
typeinterval_timer_status =
Unix.interval_timer_status
= {
|
it_interval : |
(* | 周期 | *) |
|
it_value : |
(* | 计时器的当前值 | *) |
}
描述间隔计时器状态的类型
val getitimer : interval_timer -> interval_timer_status
返回给定间隔计时器的当前状态。
Invalid_argument
val setitimer : interval_timer ->
interval_timer_status -> interval_timer_status
setitimer t s
设置间隔计时器 t
并返回其先前状态。 s
参数的解释如下:s.it_value
(如果非零)是到下一个计时器到期的时间;s.it_interval
(如果非零)指定在计时器到期时用于重新加载 it_value
的值。 将 s.it_value
设置为零将禁用计时器。 将 s.it_interval
设置为零会导致计时器在下一个到期后被禁用。
Invalid_argument
val getuid : unit -> int
返回执行进程的用户 ID。
在 Windows 上:始终返回 1
。
val geteuid : unit -> int
返回进程运行的有效用户 ID。
在 Windows 上:始终返回 1
。
val setuid : int -> unit
设置进程的真实用户 ID 和有效用户 ID。
Invalid_argument
val getgid : unit -> int
返回执行进程的组 ID。
在 Windows 上:始终返回 1
。
val getegid : unit -> int
返回进程运行的有效组 ID。
在 Windows 上:始终返回 1
。
val setgid : int -> unit
设置进程的真实组 ID 和有效组 ID。
Invalid_argument
val getgroups : unit -> int array
返回执行进程的用户所属的组列表。
在 Windows 上:始终返回 [|1|]
。
val setgroups : int array -> unit
setgroups groups
设置调用进程的补充组 ID。 需要适当的权限。
Invalid_argument
val initgroups : string -> int -> unit
initgroups user group
通过读取组数据库 /etc/group 并使用 user
是成员的所有组来初始化组访问列表。 附加组 group
也将添加到列表中。
Invalid_argument
typepasswd_entry =
Unix.passwd_entry
= {
|
pw_name : |
|
pw_passwd : |
|
pw_uid : |
|
pw_gid : |
|
pw_gecos : |
|
pw_dir : |
|
pw_shell : |
}
passwd
数据库中条目的结构。
typegroup_entry =
Unix.group_entry
= {
|
gr_name : |
|
gr_passwd : |
|
gr_gid : |
|
gr_mem : |
}
groups
数据库中条目的结构。
val getlogin : unit -> string
返回执行进程的用户登录名。
val getpwnam : string -> passwd_entry
在 passwd
中查找具有给定名称的条目。
Not_found
;或者在 Windows 上始终为 Not_found
。val getgrnam : string -> group_entry
在 group
中查找具有给定名称的条目。
Not_found
;或者在 Windows 上始终为 Not_found
。val getpwuid : int -> passwd_entry
在 passwd
中查找具有给定用户 ID 的条目。
Not_found
;或者在 Windows 上始终为 Not_found
。val getgrgid : int -> group_entry
在 group
中查找具有给定组 ID 的条目。
Not_found
;或者在 Windows 上始终为 Not_found
。typeinet_addr =
Unix.inet_addr
Internet 地址的抽象类型。
val inet_addr_of_string : string -> inet_addr
从 Internet 地址的可打印表示形式转换为其内部表示形式。 参数字符串包含 4 个用点分隔的数字(XXX.YYY.ZZZ.TTT
)用于 IPv4 地址,以及最多 8 个用冒号分隔的数字用于 IPv6 地址。
Failure
。val string_of_inet_addr : inet_addr -> string
返回给定 Internet 地址的可打印表示形式。 有关可打印表示形式的描述,请参阅 UnixLabels.inet_addr_of_string
。
val inet_addr_any : inet_addr
一个特殊的 IPv4 地址,仅与 bind
一起使用,表示主机拥有的所有 Internet 地址。
val inet_addr_loopback : inet_addr
表示主机(127.0.0.1
)的特殊 IPv4 地址。
val inet6_addr_any : inet_addr
一个特殊的 IPv6 地址,仅与 bind
一起使用,表示主机拥有的所有 Internet 地址。
val inet6_addr_loopback : inet_addr
表示主机(::1
)的特殊 IPv6 地址。
val is_inet6_addr : inet_addr -> bool
给定的 inet_addr
是否为 IPv6 地址。
typesocket_domain =
Unix.socket_domain
=
| |
PF_UNIX |
(* | Unix 域 | *) |
| |
PF_INET |
(* | Internet 域 (IPv4) | *) |
| |
PF_INET6 |
(* | Internet 域 (IPv6) | *) |
套接字域的类型。 并非所有平台都支持 IPv6 套接字(类型 PF_INET6
)。
在 Windows 上:自 4.14.0 起支持 PF_UNIX
,在 Windows 10 1803 及更高版本上支持。
typesocket_type =
Unix.socket_type
=
| |
SOCK_STREAM |
(* | 流套接字 | *) |
| |
SOCK_DGRAM |
(* | 数据报套接字 | *) |
| |
SOCK_RAW |
(* | 原始套接字 | *) |
| |
SOCK_SEQPACKET |
(* | 排序数据包套接字 | *) |
套接字类型的种类,指定通信的语义。SOCK_SEQPACKET
出于完整性而包含在内,但很少受操作系统支持,并且需要此库中不可用的系统调用。
typesockaddr =
Unix.sockaddr
=
| |
ADDR_UNIX of |
| |
ADDR_INET of |
套接字地址的类型。ADDR_UNIX name
是 Unix 域中的套接字地址;name
是文件系统中的文件名。ADDR_INET(addr,port)
是互联网域中的套接字地址;addr
是机器的互联网地址,port
是端口号。
val socket : ?cloexec:bool ->
domain:socket_domain ->
kind:socket_type -> protocol:int -> file_descr
在给定域中创建一个新的套接字,并使用给定的类型。第三个参数是协议类型;0 选择该类型套接字的默认协议。有关 cloexec
可选参数的文档,请参见 UnixLabels.set_close_on_exec
。
val domain_of_sockaddr : sockaddr -> socket_domain
返回适合给定套接字地址的套接字域。
val socketpair : ?cloexec:bool ->
domain:socket_domain ->
kind:socket_type ->
protocol:int -> file_descr * file_descr
创建一个连接在一起的无名套接字对。有关 cloexec
可选参数的文档,请参见 UnixLabels.set_close_on_exec
。
val accept : ?cloexec:bool ->
file_descr -> file_descr * sockaddr
接受给定套接字上的连接。返回的描述符是连接到客户端的套接字;返回的地址是连接客户端的地址。有关 cloexec
可选参数的文档,请参见 UnixLabels.set_close_on_exec
。
val bind : file_descr -> addr:sockaddr -> unit
将套接字绑定到地址。
val connect : file_descr -> addr:sockaddr -> unit
将套接字连接到地址。
val listen : file_descr -> max:int -> unit
为接收连接请求设置套接字。整数参数是待处理请求的最大数量。
typeshutdown_command =
Unix.shutdown_command
=
| |
SHUTDOWN_RECEIVE |
(* | 关闭接收 | *) |
| |
SHUTDOWN_SEND |
(* | 关闭发送 | *) |
| |
SHUTDOWN_ALL |
(* | 同时关闭两者 | *) |
用于 shutdown
的命令类型。
val shutdown : file_descr -> mode:shutdown_command -> unit
关闭套接字连接。SHUTDOWN_SEND
作为第二个参数会导致连接另一端上的读取返回文件结束条件。SHUTDOWN_RECEIVE
会导致连接另一端上的写入返回关闭管道条件(SIGPIPE
信号)。
val getsockname : file_descr -> sockaddr
返回给定套接字的地址。
val getpeername : file_descr -> sockaddr
返回连接到给定套接字的主机地址。
typemsg_flag =
Unix.msg_flag
=
| |
MSG_OOB |
| |
MSG_DONTROUTE |
| |
MSG_PEEK |
val recv : file_descr ->
buf:bytes -> pos:int -> len:int -> mode:msg_flag list -> int
从连接的套接字接收数据。
val recvfrom : file_descr ->
buf:bytes ->
pos:int ->
len:int -> mode:msg_flag list -> int * sockaddr
从未连接的套接字接收数据。
val send : file_descr ->
buf:bytes -> pos:int -> len:int -> mode:msg_flag list -> int
通过连接的套接字发送数据。
val send_substring : file_descr ->
buf:string -> pos:int -> len:int -> mode:msg_flag list -> int
与 send
相同,但从字符串而不是字节序列中获取数据。
val sendto : file_descr ->
buf:bytes ->
pos:int ->
len:int -> mode:msg_flag list -> addr:sockaddr -> int
通过未连接的套接字发送数据。
val sendto_substring : file_descr ->
buf:string ->
pos:int ->
len:int -> mode:msg_flag list -> sockaddr -> int
与 sendto
相同,但从字符串而不是字节序列中获取数据。
typesocket_bool_option =
Unix.socket_bool_option
=
| |
SO_DEBUG |
(* | 记录调试信息 | *) |
| |
SO_BROADCAST |
(* | 允许发送广播消息 | *) |
| |
SO_REUSEADDR |
(* | 允许为 bind 重用本地地址 | *) |
| |
SO_KEEPALIVE |
(* | 保持连接活动 | *) |
| |
SO_DONTROUTE |
(* | 绕过标准路由算法 | *) |
| |
SO_OOBINLINE |
(* | 将带外数据保留在行内 | *) |
| |
SO_ACCEPTCONN |
(* | 报告套接字监听是否已启用 | *) |
| |
TCP_NODELAY |
(* | 控制 TCP 套接字的 Nagle 算法 | *) |
| |
IPV6_ONLY |
(* | 禁止将 IPv6 套接字绑定到 IPv4 地址 | *) |
| |
SO_REUSEPORT |
(* | 允许重用地址和端口绑定 | *) |
可以使用 UnixLabels.getsockopt
查询,并可以使用 UnixLabels.setsockopt
修改的套接字选项。这些选项具有布尔值(true
/false
)。
typesocket_int_option =
Unix.socket_int_option
=
| |
SO_SNDBUF |
(* | 发送缓冲区的大小 | *) |
| |
SO_RCVBUF |
(* | 接收缓冲区的大小 | *) |
| |
SO_ERROR |
(* |
已弃用。 请改用 Unix.getsockopt_error。
已弃用。请改用 | *) |
| |
SO_TYPE |
(* | 报告套接字类型 | *) |
| |
SO_RCVLOWAT |
(* | 对输入操作进行处理的最小字节数 | *) |
| |
SO_SNDLOWAT |
(* | 对输出操作进行处理的最小字节数 | *) |
可以使用 UnixLabels.getsockopt_int
查询,并可以使用 UnixLabels.setsockopt_int
修改的套接字选项。这些选项具有整数值。
typesocket_optint_option =
Unix.socket_optint_option
=
| |
SO_LINGER |
(* | 是否在存在数据的关闭连接上停留,以及停留多长时间(以秒为单位) | *) |
可以使用 UnixLabels.getsockopt_optint
查询,并可以使用 UnixLabels.setsockopt_optint
修改的套接字选项。这些选项的值类型为 int option
,其中 None
表示“禁用”。
typesocket_float_option =
Unix.socket_float_option
=
| |
SO_RCVTIMEO |
(* | 输入操作的超时时间 | *) |
| |
SO_SNDTIMEO |
(* | 输出操作的超时时间 | *) |
可以使用 UnixLabels.getsockopt_float
查询,并可以使用 UnixLabels.setsockopt_float
修改的套接字选项。这些选项具有表示以秒为单位的时间的浮点值。值 0 表示无限超时。
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
与 UnixLabels.getsockopt
相同,用于整数值套接字选项。
val setsockopt_int : file_descr -> socket_int_option -> int -> unit
与 UnixLabels.setsockopt
相同,用于整数值套接字选项。
val getsockopt_optint : file_descr -> socket_optint_option -> int option
与 UnixLabels.getsockopt
相同,用于值为 int option
的套接字选项。
val setsockopt_optint : file_descr ->
socket_optint_option -> int option -> unit
与 UnixLabels.setsockopt
相同,用于值为 int option
的套接字选项。
val getsockopt_float : file_descr -> socket_float_option -> float
与 UnixLabels.getsockopt
相同,用于值为浮点数的套接字选项。
val setsockopt_float : file_descr -> socket_float_option -> float -> unit
与 UnixLabels.setsockopt
相同,用于值为浮点数的套接字选项。
val getsockopt_error : file_descr -> error option
返回与给定套接字关联的错误条件,并清除它。
val open_connection : sockaddr -> in_channel * out_channel
val shutdown_connection : in_channel -> unit
“关闭”使用 UnixLabels.open_connection
建立的连接;也就是说,将文件结束条件传输到连接另一端读取的服务器。这不会关闭套接字和连接使用的通道。有关连接结束后如何关闭它们,请参见 Unix.open_connection
。
val establish_server : (in_channel -> out_channel -> unit) ->
addr:sockaddr -> unit
在给定地址上建立服务器。作为第一个参数给出的函数针对每个连接调用,并使用连接到客户端的两个缓冲通道。针对每个连接创建新的进程。UnixLabels.establish_server
函数永远不会正常返回。
给定函数的两个通道共享一个指向套接字的描述符。函数不需要关闭通道,因为这会在函数返回时自动发生。如果函数更喜欢显式关闭,它应该使用 close_out
关闭输出通道,并将输入通道保持未关闭状态,原因在 Unix.in_channel_of_descr
中进行了说明。
Invalid_argument
。请改用线程。typehost_entry =
Unix.host_entry
= {
|
h_name : |
|
h_aliases : |
|
h_addrtype : |
|
h_addr_list : |
}
hosts
数据库中条目的结构。
typeprotocol_entry =
Unix.protocol_entry
= {
|
p_name : |
|
p_aliases : |
|
p_proto : |
}
protocols
数据库中条目的结构。
typeservice_entry =
Unix.service_entry
= {
|
s_name : |
|
s_aliases : |
|
s_port : |
|
s_proto : |
}
services
数据库中条目的结构。
val gethostname : unit -> string
返回本地主机的名称。
val gethostbyname : string -> host_entry
在 hosts
中查找具有给定名称的条目。
Not_found
。val gethostbyaddr : inet_addr -> host_entry
在 hosts
中查找具有给定地址的条目。
Not_found
。val getprotobyname : string -> protocol_entry
在 protocols
中查找具有给定名称的条目。
Not_found
。val getprotobynumber : int -> protocol_entry
在 protocols
中查找具有给定协议号的条目。
Not_found
。val getservbyname : string -> protocol:string -> service_entry
在 services
中查找具有给定名称的条目。
Not_found
。val getservbyport : int -> protocol:string -> service_entry
在 services
中查找具有给定服务号的条目。
Not_found
。typeaddr_info =
Unix.addr_info
= {
|
ai_family : |
(* | 套接字域 | *) |
|
ai_socktype : |
(* | 套接字类型 | *) |
|
ai_protocol : |
(* | 套接字协议号 | *) |
|
ai_addr : |
(* | 地址 | *) |
|
ai_canonname : |
(* | 规范主机名 | *) |
}
由 UnixLabels.getaddrinfo
返回的地址信息。
typegetaddrinfo_option =
Unix.getaddrinfo_option
=
| |
AI_FAMILY of |
(* | 施加给定的套接字域 | *) |
| |
AI_SOCKTYPE of |
(* | 施加给定的套接字类型 | *) |
| |
AI_PROTOCOL of |
(* | 施加给定的协议 | *) |
| |
AI_NUMERICHOST |
(* | 不要调用名称解析器,预期为数字 IP 地址 | *) |
| |
AI_CANONNAME |
(* | 填充结果的 | *) |
| |
AI_PASSIVE |
(* | 将地址设置为“任何”地址,用于 | *) |
选项用于 UnixLabels.getaddrinfo
.
val getaddrinfo : string ->
string -> getaddrinfo_option list -> addr_info list
getaddrinfo host service opts
返回一个 UnixLabels.addr_info
记录列表,描述了用于与给定主机和服务通信的套接字参数和地址。如果主机或服务名称未知,或者 opts
中表达的约束条件无法满足,则返回空列表。
host
是主机名或 IP 地址的字符串表示。 host
可以为空字符串;在这种情况下,将使用“任何”地址或“环回”地址,具体取决于 opts
是否包含 AI_PASSIVE
。 service
是服务名称或端口号的字符串表示。 service
可以为空字符串;在这种情况下,返回地址的端口字段将设置为 0。 opts
是一个可能为空的选项列表,允许调用者强制使用特定的套接字域(例如,仅 IPv6 或仅 IPv4)或特定的套接字类型(例如,仅 TCP 或仅 UDP)。
typename_info =
Unix.name_info
= {
|
ni_hostname : |
(* | 主机名称或 IP 地址 | *) |
|
ni_service : |
(* | 服务名称或端口号 | *) |
}
由 UnixLabels.getnameinfo
返回的主机和服务信息。
typegetnameinfo_option =
Unix.getnameinfo_option
=
| |
NI_NOFQDN |
(* | 不要限定本地主机名 | *) |
| |
NI_NUMERICHOST |
(* | 始终将主机作为 IP 地址返回 | *) |
| |
NI_NAMEREQD |
(* | 如果无法确定主机名,则失败 | *) |
| |
NI_NUMERICSERV |
(* | 始终将服务作为端口号返回 | *) |
| |
NI_DGRAM |
(* | 将服务视为基于 UDP,而不是默认的 TCP | *) |
选项用于 UnixLabels.getnameinfo
.
val getnameinfo : sockaddr ->
getnameinfo_option list -> name_info
getnameinfo addr opts
返回与套接字地址 addr
相对应的主机名和服务名。 opts
是一个可能为空的选项列表,它控制这些名称是如何获取的。
Not_found
如果发生错误。以下函数实现了 POSIX 标准终端接口。它们提供对异步通信端口和伪终端的控制。有关完整描述,请参阅 termios
手册页。
typeterminal_io =
Unix.terminal_io
= {
|
mutable c_ignbrk : |
(* | 忽略中断条件。 | *) |
|
mutable c_brkint : |
(* | 在中断条件下发出中断信号。 | *) |
|
mutable c_ignpar : |
(* | 忽略奇偶校验错误的字符。 | *) |
|
mutable c_parmrk : |
(* | 标记奇偶校验错误。 | *) |
|
mutable c_inpck : |
(* | 启用输入的奇偶校验检查。 | *) |
|
mutable c_istrip : |
(* | 剥离输入字符的第 8 位。 | *) |
|
mutable c_inlcr : |
(* | 将 NL 映射到输入的 CR。 | *) |
|
mutable c_igncr : |
(* | 忽略输入的 CR。 | *) |
|
mutable c_icrnl : |
(* | 将 CR 映射到输入的 NL。 | *) |
|
mutable c_ixon : |
(* | 识别输入的 XON/XOFF 字符。 | *) |
|
mutable c_ixoff : |
(* | 发出 XON/XOFF 字符来控制输入流。 | *) |
|
mutable c_opost : |
(* | 启用输出处理。 | *) |
|
mutable c_obaud : |
(* | 输出波特率(0 表示关闭连接)。 | *) |
|
mutable c_ibaud : |
(* | 输入波特率。 | *) |
|
mutable c_csize : |
(* | 每个字符的位数(5-8)。 | *) |
|
mutable c_cstopb : |
(* | 停止位的数量(1-2)。 | *) |
|
mutable c_cread : |
(* | 接收已启用。 | *) |
|
mutable c_parenb : |
(* | 启用奇偶校验生成和检测。 | *) |
|
mutable c_parodd : |
(* | 指定奇校验而不是偶校验。 | *) |
|
mutable c_hupcl : |
(* | 在最后一次关闭时挂断。 | *) |
|
mutable c_clocal : |
(* | 忽略调制解调器状态线。 | *) |
|
mutable c_isig : |
(* | 在 INTR、QUIT、SUSP 上生成信号。 | *) |
|
mutable c_icanon : |
(* | 启用规范处理(行缓冲和编辑) | *) |
|
mutable c_noflsh : |
(* | 在 INTR、QUIT、SUSP 后禁用刷新。 | *) |
|
mutable c_echo : |
(* | 回显输入字符。 | *) |
|
mutable c_echoe : |
(* | 回显 ERASE(擦除前一个字符)。 | *) |
|
mutable c_echok : |
(* | 回显 KILL(擦除当前行)。 | *) |
|
mutable c_echonl : |
(* | 即使未设置 c_echo,也回显 NL。 | *) |
|
mutable c_vintr : |
(* | 中断字符(通常为 ctrl-C)。 | *) |
|
mutable c_vquit : |
(* | 退出字符(通常为 ctrl-\)。 | *) |
|
mutable c_verase : |
(* | 擦除字符(通常为 DEL 或 ctrl-H)。 | *) |
|
mutable c_vkill : |
(* | 杀死行字符(通常为 ctrl-U)。 | *) |
|
mutable c_veof : |
(* | 文件结束符(通常为 ctrl-D)。 | *) |
|
mutable c_veol : |
(* | 备用换行符(通常为无)。 | *) |
|
mutable c_vmin : |
(* | 在读取请求满足之前要读取的最小字符数。 | *) |
|
mutable c_vtime : |
(* | 最大读取等待时间(以 0.1 秒为单位)。 | *) |
|
mutable c_vstart : |
(* | 启动字符(通常为 ctrl-Q)。 | *) |
|
mutable c_vstop : |
(* | 停止字符(通常为 ctrl-S)。 | *) |
}
val tcgetattr : file_descr -> terminal_io
返回给定文件描述符所引用的终端的状态。
Invalid_argument
typesetattr_when =
Unix.setattr_when
=
| |
TCSANOW |
| |
TCSADRAIN |
| |
TCSAFLUSH |
val tcsetattr : file_descr ->
mode:setattr_when -> terminal_io -> unit
设置给定文件描述符所引用的终端的状态。第二个参数指示状态更改发生的时间:立即(TCSANOW
)、当所有待发送的输出都已发送时(TCSADRAIN
),或者在刷新所有已接收但尚未读取的输入后(TCSAFLUSH
)。当更改输出参数时,建议使用 TCSADRAIN
;当更改输入参数时,建议使用 TCSAFLUSH
。
Invalid_argument
val tcsendbreak : file_descr -> duration:int -> unit
在给定文件描述符上发送中断条件。第二个参数是中断的持续时间,以 0.1 秒为单位;0 表示标准持续时间(0.25 秒)。
Invalid_argument
val tcdrain : file_descr -> unit
等待直到所有写入给定文件描述符的输出都已发送。
Invalid_argument
typeflush_queue =
Unix.flush_queue
=
| |
TCIFLUSH |
| |
TCOFLUSH |
| |
TCIOFLUSH |
val tcflush : file_descr -> mode:flush_queue -> unit
丢弃写入给定文件描述符但尚未发送的数据,或者接收但尚未读取的数据,具体取决于第二个参数:TCIFLUSH
刷新已接收但尚未读取的数据,TCOFLUSH
刷新已写入但尚未发送的数据,TCIOFLUSH
同时刷新两者。
Invalid_argument
typeflow_action =
Unix.flow_action
=
| |
TCOOFF |
| |
TCOON |
| |
TCIOFF |
| |
TCION |
val tcflow : file_descr -> mode:flow_action -> unit
暂停或重新开始对给定文件描述符的数据接收或传输,具体取决于第二个参数:TCOOFF
暂停输出,TCOON
重新开始输出,TCIOFF
发送一个 STOP 字符来暂停输入,TCION
发送一个 START 字符来重新开始输入。
Invalid_argument
val setsid : unit -> int
将调用进程置于一个新的会话中,并将其从其控制终端分离。
Invalid_argument