模組 Unix

module Unix: sig .. end

與 Unix 系統的介面。

若要使用此模組的標籤版本,請在您的實作中加入 module Unix = UnixLabels

注意:此模組的所有函式(除了 Unix.error_messageUnix.handle_unix_error)在底層系統呼叫發出錯誤訊號時,都可能會引發 Unix.Unix_error 例外。


錯誤報告

type 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 int (*

未知錯誤

*)

錯誤碼的類型。POSIX 標準中定義的錯誤以及來自 UNIX98 和 BSD 的其他錯誤。所有其他錯誤都會映射到 EUNKNOWNERR。

exception Unix_error of error * string * string

當遇到錯誤時,由下方的系統呼叫引發。第一個元件是錯誤碼;第二個元件是函式名稱;第三個元件是函式的字串參數(如果有),否則為空字串。

UnixLabels.Unix_errorUnix.Unix_error 是相同的,捕捉其中一個也會捕捉到另一個。

val error_message : error -> string

傳回描述指定錯誤碼的字串。

val handle_unix_error : ('a -> 'b) -> 'a -> 'b

handle_unix_error f xf 套用至 x 並傳回結果。如果引發 Unix.Unix_error 例外,則會列印描述錯誤的訊息,並以代碼 2 結束。

存取程序環境

val environment : unit -> string array

傳回程序環境,以格式為 ``variable=value'' 的字串陣列表示。如果程序具有特殊權限,則傳回的陣列為空。

val unsafe_environment : unit -> string array

傳回程序環境,以格式為 ``variable=value'' 的字串陣列表示。與 Unix.environment 不同,即使程序具有特殊權限,此函式也會傳回已填入的陣列。如需更多詳細資訊,請參閱 Unix.unsafe_getenv 的文件。

val getenv : string -> string

傳回與程序環境中的變數關聯的值,除非程序具有特殊權限。

val unsafe_getenv : string -> string

傳回與程序環境中的變數關聯的值。

Unix.getenv 不同,即使程序具有特殊權限,此函式也會傳回該值。它被認為是不安全的,因為 setuid 或 setgid 程式的程式設計人員必須小心避免在可執行檔的搜尋路徑、暫存檔或記錄檔的位置等中使用惡意製作的環境變數。

val putenv : string -> string -> unit

putenv name value 設定程序環境中與變數關聯的值。name 是環境變數的名稱,而 value 是其新的關聯值。

程序處理

type process_status = 
| WEXITED of int (*

程序正常終止,透過 exit;引數為傳回碼。

*)
| WSIGNALED of int (*

程序被訊號終止;引數為訊號編號。

*)
| WSTOPPED of int (*

程序被訊號停止;引數為訊號編號。

*)

程序的終止狀態。請參閱模組 Sys 以取得標準訊號編號的定義。請注意,它們並非作業系統所使用的編號。

在 Windows 上:僅使用 WEXITED (因為沒有程序間訊號),但使用特定的傳回碼來表示特殊的終止原因。在 Windows 文件中尋找 NTSTATUS 值來解碼此類錯誤傳回碼。特別是,STATUS_ACCESS_VIOLATION 錯誤碼是 32 位元的 0xC0000005:因為 Int32.of_int 0xC0000005-1073741819,所以 WEXITED -1073741819 是 Windows 上與 WSIGNALED Sys.sigsegv 等效的表示法。

type wait_flag = 
| WNOHANG (*

如果沒有子程序結束,則不要封鎖,而是立即傳回 PID 等於 0 的值。

*)
| WUNTRACED (*

也回報收到停止訊號的子程序。

*)

Unix.waitpid 的旗標。

val execv : string -> string array -> 'a

execv prog args 使用引數 args 和目前程序環境執行檔案 prog 中的程式。請注意,依照慣例,第一個引數 args.(0) 是正在執行的程式的檔案名稱,就像 Sys.argv.(0) 一樣。這些 execv* 函式永遠不會傳回:在成功時,目前程式會被新的程式取代。

在 Windows 上:CRT 只會產生新的程序並結束目前的程序。如果例如另一個程序正在等待目前的程序,這將會產生不良的後果。建議改用 Unix.create_process 或其中一個 open_process_* 函式。

val execve : string -> string array -> string array -> 'a

Unix.execv 相同,不同之處在於第三個引數提供要執行的程式的環境。

val execvp : string -> string array -> 'a

Unix.execv 相同,不同之處在於會在路徑中搜尋程式。

val execvpe : string -> string array -> string array -> 'a

Unix.execve 相同,不同之處在於會在路徑中搜尋程式。

val fork : unit -> int

衍生一個新的程序。回傳的整數值對於子程序為 0,對於父程序則為子程序的 pid。如果 OCaml 程序是多核心的(已產生任何 domain),則會失敗。此外,如果已產生 Thread 模組的任何執行緒,則子程序可能會處於損毀的狀態。

val wait : unit -> int * process_status

等待其中一個子程序終止,並回傳其 pid 和終止狀態。

val waitpid : wait_flag list -> int -> int * process_status

Unix.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。

val nice : int -> int

變更程序優先順序。整數引數會加到「nice」值。(「nice」值較高表示優先順序較低。)回傳新的 nice 值。

基本檔案輸入/輸出

type file_descr 

檔案描述符的抽象類型。

val stdin : file_descr

標準輸入的檔案描述符。

val stdout : file_descr

標準輸出的檔案描述符。

val stderr : file_descr

標準錯誤的檔案描述符。

type 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 (*

Unix.openfile 回傳的描述符上設定 close-on-exec 旗標。如需詳細資訊,請參閱 Unix.set_close_on_exec

*)
| O_KEEPEXEC (*

清除 close-on-exec 旗標。目前這是預設值。

*)

Unix.openfile 的旗標。

type file_perm = int 

檔案存取權的類型,例如 0o640 表示使用者可讀寫、群組可讀、其他人沒有權限

val openfile : string -> open_flag list -> file_perm -> file_descr

使用給定的旗標開啟指定的檔案。第三個引數是建立檔案時要給予的權限 (請參閱 Unix.umask)。回傳指定檔案的檔案描述符。

val close : file_descr -> unit

關閉檔案描述符。

val fsync : file_descr -> unit

將檔案緩衝區清除到磁碟。

val read : file_descr -> bytes -> int -> int -> int

read fd buf pos len 從描述符 fd 讀取 len 個位元組,將它們儲存在位元組序列 buf 中,從 buf 中的位置 pos 開始。回傳實際讀取的位元組數。

val read_bigarray : file_descr ->
('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray.Array1.t -> int -> int -> int

Unix.read 相同,但將資料讀取到大陣列中。

val write : file_descr -> bytes -> int -> int -> int

write fd buf pos lenlen 個位元組寫入描述符 fd,從位元組序列 buf 中取得它們,從 buff 中的位置 pos 開始。回傳實際寫入的位元組數。write 會重複寫入作業,直到所有位元組都已寫入或發生錯誤為止。

val write_bigarray : file_descr ->
('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray.Array1.t -> int -> int -> int

Unix.write 相同,但從大陣列取得資料。

val single_write : file_descr -> bytes -> int -> int -> int

Unix.write 相同,但嘗試只寫入一次。因此,如果發生錯誤,single_write 保證沒有寫入任何資料。

val write_substring : file_descr -> string -> int -> int -> int

Unix.write 相同,但從字串取得資料,而非位元組序列。

val single_write_substring : file_descr -> string -> int -> int -> int

Unix.single_write 相同,但從字串取得資料,而非位元組序列。

val single_write_bigarray : file_descr ->
('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray.Array1.t -> int -> int -> int

Unix.single_write 相同,但從大陣列取得資料。

與標準輸入/輸出函式庫介接

val in_channel_of_descr : file_descr -> in_channel

建立一個從給定描述符讀取的輸入通道。該通道最初處於二進位模式;如果需要文字模式,請使用 set_binary_mode_in ic false。僅當描述符參照檔案或管道時才支援文字模式,但如果參照 socket,則不支援文字模式。

在 Windows 上:set_binary_mode_in 在使用此函式建立的通道上始終失敗。

請注意,輸入通道會被緩衝,因此從描述符讀取的字元數可能多於使用通道函式存取的字元數。通道也會保留檔案中目前位置的複本。

使用 close_in ic 關閉 in_channel_of_descr fd 回傳的通道 ic,也會關閉基礎描述符 fd。同時關閉通道 ic 和描述符 fd 是不正確的。

如果從同一個描述符建立多個通道,則必須關閉其中一個通道,但其他通道不能關閉。例如,考慮連接到 socket 的描述符 s 以及兩個通道 ic = in_channel_of_descr soc = out_channel_of_descr s。建議的關閉協定是執行 close_out oc,這會將緩衝輸出清除到 socket,然後關閉 socket。ic 通道不得關閉,最終會被 GC 收集。

val out_channel_of_descr : file_descr -> out_channel

建立一個在給定描述符上寫入的輸出通道。該通道最初處於二進位模式;如果需要文字模式,請使用 set_binary_mode_out oc false。僅當描述符參照檔案或管道時才支援文字模式,但如果參照 socket,則不支援文字模式。

在 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

回傳對應於輸出通道的描述符。

搜尋與截斷

type seek_command = 
| SEEK_SET (*

表示相對於檔案開頭的位置

*)
| SEEK_CUR (*

表示相對於目前位置的位置

*)
| SEEK_END (*

表示相對於檔案結尾的位置

*)

Unix.lseek 的定位模式。

val lseek : file_descr -> int -> seek_command -> int

設定檔案描述符的目前位置,並回傳產生的位移 (從檔案開頭算起)。

val truncate : string -> int -> unit

將指定的檔案截斷為給定大小。

val ftruncate : file_descr -> int -> unit

將對應於給定描述符的檔案截斷為給定大小。

檔案狀態

type file_kind = 
| S_REG (*

一般檔案

*)
| S_DIR (*

目錄

*)
| S_CHR (*

字元裝置

*)
| S_BLK (*

區塊裝置

*)
| S_LNK (*

符號連結

*)
| S_FIFO (*

具名管道

*)
| S_SOCK (*

Socket

*)
type stats = {
   st_dev : int; (*

裝置編號

*)
   st_ino : int; (*

inode 編號

*)
   st_kind : file_kind; (*

檔案類型

*)
   st_perm : file_perm; (*

存取權限

*)
   st_nlink : int; (*

連結數

*)
   st_uid : int; (*

擁有者的使用者 ID

*)
   st_gid : int; (*

檔案群組的群組 ID

*)
   st_rdev : int; (*

裝置 ID (如果是特殊檔案)

*)
   st_size : int; (*

大小 (以位元組為單位)

*)
   st_atime : float; (*

上次存取時間

*)
   st_mtime : float; (*

上次修改時間

*)
   st_ctime : float; (*

上次狀態變更時間

*)
}

Unix.stat 呼叫所傳回的資訊。

val stat : string -> stats

傳回指定檔案的資訊。

val lstat : string -> stats

Unix.stat 相同,但如果檔案是符號連結,則傳回連結本身的資訊。

val fstat : file_descr -> stats

傳回與指定描述符關聯的檔案資訊。

val isatty : file_descr -> bool

如果指定的檔案描述符指向終端機或主控台視窗,則傳回 true,否則傳回 false

大型檔案的檔案操作

module LargeFile: sig .. end

對大型檔案進行檔案操作。

將檔案映射到記憶體

val map_file : file_descr ->
?pos:int64 ->
('a, 'b) Bigarray.kind ->
'c Bigarray.layout ->
bool -> int array -> ('a, 'b, 'c) Bigarray.Genarray.t

將檔案以 Bigarray 的形式進行記憶體映射。map_file fd kind layout shared dims 傳回一個 Bigarray,其種類為 kind,佈局為 layout,並且維度如 dims 中指定。此 Bigarray 中包含的資料是檔案描述符 fd 所參照的檔案內容(例如,之前使用 Unix.openfile 開啟)。可選的 pos 參數是要映射的資料在檔案中的位元組偏移量;預設值為 0(從檔案開頭開始映射)。

如果 sharedtrue,則對陣列執行的所有修改都會反映在檔案中。這需要以寫入權限開啟 fd。如果 sharedfalse,則對陣列執行的修改僅在記憶體中完成,使用修改頁面的寫入時複製;底層檔案不受影響。

Unix.map_file 比將整個檔案讀入 Bigarray,修改該 Bigarray,然後再寫入效率高得多。

要將 Bigarray 的維度自動調整為檔案的實際大小,主要維度(即,對於 C 佈局的陣列,是第一個維度;對於 Fortran 佈局的陣列,是最後一個維度)可以給定為 -1Unix.map_file 然後會從檔案大小確定主要維度。檔案必須包含整數個子陣列,如非主要維度所確定,否則會引發 Failure

如果給定了 Bigarray 的所有維度,則會將檔案大小與 Bigarray 的大小進行匹配。如果檔案大於 Bigarray,則只有檔案的初始部分會映射到 Bigarray。如果檔案小於 Bigarray,則檔案會自動增長到 Bigarray 的大小。這需要在 fd 上具有寫入權限。

陣列存取會進行邊界檢查,但邊界是由最初的 map_file 呼叫確定的。因此,您應確保在您存取時,沒有其他程序修改已映射的檔案,否則可能會引發 SIGBUS 訊號。例如,如果檔案縮小時就會發生這種情況。

在引數驗證失敗的情況下,可能會引發 Invalid_argumentFailure

檔案名稱的操作

val unlink : string -> unit

移除指定的檔案。

如果指定的檔案是目錄,則引發

  • 在符合 POSIX 標準的系統上引發 EPERM
  • 在 Linux >= 2.1.132 上引發 EISDIR
  • 在 Windows 上引發 EACCESS
val rename : string -> string -> unit

rename src dst 將檔案名稱從 src 變更為 dst,並在需要時在目錄之間移動。如果 dst 已存在,則其內容將被 src 的內容取代。根據作業系統,dst 的中繼資料(權限、擁有者等)可以保留或由 src 的中繼資料取代。

val link : ?follow:bool -> string -> string -> unit

link ?follow src dst 建立名為 dst 的硬連結,指向名為 src 的檔案。

follow:指示是否追蹤 src 符號連結,或者是否建立指向 src 本身的硬連結。在 *Unix* 系統上,這是使用 linkat(2) 函數完成的。如果未提供 ?follow,則會使用 link(2) 函數,其行為取決於作業系統,但更廣泛可用。
val realpath : string -> string

realpath pp 的絕對路徑名稱,透過解析所有額外的 / 字元、相對路徑區段和符號連結取得。

檔案權限與擁有權

type access_permission = 
| R_OK (*

讀取權限

*)
| W_OK (*

寫入權限

*)
| X_OK (*

執行權限

*)
| F_OK (*

檔案已存在

*)

Unix.access 呼叫的旗標。

val chmod : string -> file_perm -> unit

變更指定檔案的權限。

val fchmod : file_descr -> file_perm -> unit

變更已開啟檔案的權限。

val chown : string -> int -> int -> unit

變更指定檔案的擁有者 uid 和擁有者 gid。

val fchown : file_descr -> int -> int -> unit

變更已開啟檔案的擁有者 uid 和擁有者 gid。

val umask : file_perm -> file_perm

設定程序的檔案模式建立遮罩,並傳回先前的遮罩。

val access : string -> access_permission list -> unit

檢查程序是否具有指定檔案的指定權限。

在 Windows 上:無法測試執行權限 X_OK,而是測試讀取權限。

檔案描述符的操作

val dup : ?cloexec:bool -> file_descr -> file_descr

傳回一個新的檔案描述符,該描述符引用與指定描述符相同的檔案。請參閱 Unix.set_close_on_exec 以取得有關 cloexec 可選引數的說明文件。

val dup2 : ?cloexec:bool -> file_descr -> file_descr -> unit

dup2 src dstsrc 複製到 dst,如果 dst 已開啟,則關閉 dst。請參閱 Unix.set_close_on_exec 以取得有關 cloexec 可選引數的說明文件。

val set_nonblock : file_descr -> unit

設定指定描述符上的「非封鎖」旗標。設定非封鎖旗標後,在暫時沒有可用資料的描述符上讀取會引發 EAGAINEWOULDBLOCK 錯誤,而不是封鎖;在暫時沒有寫入空間的描述符上寫入也會引發 EAGAINEWOULDBLOCK

val clear_nonblock : file_descr -> unit

清除指定描述符上的「非封鎖」旗標。請參閱 Unix.set_nonblock

val set_close_on_exec : file_descr -> unit

設定指定描述符上的「執行時關閉」旗標。當目前的程序使用 execcreate_processopen_process 函數之一啟動另一個程式時,具有「執行時關閉」旗標的描述符會自動關閉。

將在例如私有檔案上開啟的檔案描述符洩漏給外部程式通常是一個安全漏洞:然後,該程式可以存取該私有檔案並對其執行不好的操作。因此,強烈建議將所有檔案描述符設定為「執行時關閉」,除非在極少數情況下,需要將檔案描述符傳輸到另一個程式。

設定檔案描述符「執行時關閉」的最佳方式是在此狀態下建立它。為此,openfile 函數具有 O_CLOEXECO_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

清除指定描述符上的「執行時關閉」旗標。請參閱 Unix.set_close_on_exec

目錄

val mkdir : string -> file_perm -> unit

使用給定的權限建立目錄(請參閱 Unix.umask)。

val rmdir : string -> unit

移除空目錄。

val chdir : string -> unit

變更程序的工作目錄。

val getcwd : unit -> string

傳回目前工作目錄的名稱。

val chroot : string -> unit

變更程序的根目錄。

type 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

建立一個管道。結果的第一個組件會開啟用於讀取,這就是管道的出口。第二個組件會開啟用於寫入,這就是管道的入口。關於 cloexec 可選參數的文件,請參閱 Unix.set_close_on_exec

val mkfifo : string -> file_perm -> unit

建立一個具有指定權限的具名管道(請參閱 Unix.umask)。

高階程序與重新導向管理

val create_process : string ->
string array -> file_descr -> file_descr -> file_descr -> int

create_process prog args stdin stdout stderr 會建立一個新的程序,執行檔案 prog 中的程式,並使用參數 args。請注意,按照慣例,第一個參數 args.(0) 是正在執行的程式的檔案名稱,就像 Sys.argv.(0) 一樣。新程序的 pid 會立即返回;新程序會與目前的程序同時執行。新程序的標準輸入和輸出會連接到描述符 stdinstdoutstderr。例如,傳遞 Unix.stdoutstdout 會防止重定向,並使新程序的標準輸出與目前程序相同。可執行檔案 prog 會在路徑中搜尋。新程序具有與目前程序相同的環境。

val create_process_env : string ->
string array ->
string array -> file_descr -> file_descr -> file_descr -> int

create_process_env prog args env stdin stdout stderr 的運作方式與 Unix.create_process 相同,不同之處在於額外參數 env 指定傳遞給程式的環境。

val open_process_in : string -> in_channel

高階的管道和程序管理。此函式會與程式平行執行指定的命令。命令的標準輸出會重定向到管道,可透過返回的輸入通道讀取。此命令會由 shell /bin/sh(或 Windows 上的 cmd.exe)解譯,請參閱 Unix.systemFilename.quote_command 函式可用於適當地引用命令及其參數,以供 shell 使用。如果命令不需要透過 shell 執行,則可以使用 Unix.open_process_args_in,作為 Unix.open_process_in 的更強大且更有效率的替代方案。

val open_process_out : string -> out_channel

Unix.open_process_in 相同,但會將命令的標準輸入重定向到管道。寫入至返回的輸出通道的資料會傳送至命令的標準輸入。警告:輸出通道上的寫入會被緩衝,因此請注意在適當的時間呼叫 flush,以確保正確同步。如果命令不需要透過 shell 執行,則可以使用 Unix.open_process_args_out,取代 Unix.open_process_out

val open_process : string -> in_channel * out_channel

Unix.open_process_out 相同,但會將命令的標準輸入和標準輸出都重定向到連接至兩個返回通道的管道。輸入通道會連接到命令的輸出,而輸出通道則會連接到命令的輸入。如果命令不需要透過 shell 執行,則可以使用 Unix.open_process_args,取代 Unix.open_process

val open_process_full : string ->
string array -> in_channel * out_channel * in_channel

類似於 Unix.open_process,但第二個參數指定傳遞給命令的環境。結果是一個由三個通道組成的三元組,分別連接到命令的標準輸出、標準輸入和標準錯誤。如果命令不需要透過 shell 執行,則可以使用 Unix.open_process_args_full,取代 Unix.open_process_full

val open_process_args : string -> string array -> in_channel * out_channel

open_process_args prog args 會執行具有參數 args 的程式 prog。請注意,按照慣例,第一個參數 args.(0) 是正在執行的程式的檔案名稱,就像 Sys.argv.(0) 一樣。新程序會與目前的程序同時執行。新程序的標準輸入和輸出會重定向到管道,可分別透過返回的通道讀取和寫入。輸入通道會連接到程式的輸出,而輸出通道則會連接到程式的輸入。

警告:輸出通道上的寫入會被緩衝,因此請注意在適當的時間呼叫 flush,以確保正確同步。

會在路徑中搜尋可執行檔案 prog。此行為在 4.12 中已變更;先前,prog 只會在目前目錄中查詢。

新程序具有與目前程序相同的環境。

val open_process_args_in : string -> string array -> in_channel

Unix.open_process_args 相同,但只會重定向新程序的標準輸出。

val open_process_args_out : string -> string array -> out_channel

Unix.open_process_args 相同,但只會重定向新程序的標準輸入。

val open_process_args_full : string ->
string array ->
string array -> in_channel * out_channel * in_channel

類似於 Unix.open_process_args,但第三個參數指定傳遞給新程序的環境。結果是一個由三個通道組成的三元組,分別連接到程式的標準輸出、標準輸入和標準錯誤。

val process_in_pid : in_channel -> int

傳回透過 Unix.open_process_args_in 開啟的程序的 pid,或透過 Unix.open_process_in 開啟的 shell 的 pid。

val process_out_pid : out_channel -> int

傳回透過 Unix.open_process_args_out 開啟的程序的 pid,或透過 Unix.open_process_out 開啟的 shell 的 pid。

val process_pid : in_channel * out_channel -> int

傳回透過 Unix.open_process_args 開啟的程序的 pid,或透過 Unix.open_process_args 開啟的 shell 的 pid。

val process_full_pid : in_channel * out_channel * in_channel -> int

傳回透過 Unix.open_process_args_full 開啟的程序的 pid,或透過 Unix.open_process_full 開啟的 shell 的 pid。

val close_process_in : in_channel -> process_status

關閉 Unix.open_process_in 開啟的通道,等待相關聯的命令終止,並傳回其終止狀態。

val close_process_out : out_channel -> process_status

關閉 Unix.open_process_out 開啟的通道,等待相關聯的命令終止,並傳回其終止狀態。

val close_process : in_channel * out_channel -> process_status

關閉 Unix.open_process 開啟的通道,等待相關聯的命令終止,並傳回其終止狀態。

val close_process_full : in_channel * out_channel * in_channel ->
process_status

關閉 Unix.open_process_full 開啟的通道,等待相關聯的命令終止,並傳回其終止狀態。

val symlink : ?to_dir:bool -> string -> 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。

可以使用 Unix.has_symlink 來檢查程序是否能夠建立符號連結。

val has_symlink : unit -> bool

如果使用者能夠建立符號連結,則會傳回 true。在 Windows 上,這表示使用者不僅具有 SeCreateSymbolicLinkPrivilege,而且還在必要時以提升的權限執行。在其他平台上,這僅表示 symlink 系統呼叫可用。

val readlink : string -> string

讀取符號連結的內容。

輪詢

val select : file_descr list ->
file_descr list ->
file_descr list ->
float -> file_descr list * file_descr list * file_descr list

等待某些輸入/輸出操作在某些通道上變成可能。三個清單參數分別是要檢查讀取(第一個參數)、寫入(第二個參數)或例外狀況(第三個參數)的描述符集。第四個參數是以秒為單位的最大逾時時間;負的第四個參數表示沒有逾時時間(無限等待)。結果由三個描述符集組成:準備好進行讀取的(第一個組件)、準備好進行寫入的(第二個組件)以及具有待處理例外狀況的(第三個組件)。

鎖定

type lock_command = 
| F_ULOCK (*

解除鎖定區域

*)
| F_LOCK (*

鎖定區域以進行寫入,如果已鎖定,則會封鎖

*)
| F_TLOCK (*

鎖定區域以進行寫入,如果已鎖定,則會失敗

*)
| F_TEST (*

測試區域是否存在其他程序鎖定

*)
| F_RLOCK (*

鎖定區域以進行讀取,如果已鎖定,則會封鎖

*)
| F_TRLOCK (*

鎖定區域以進行讀取,如果已鎖定,則會失敗

*)

Unix.lockf 的命令。

val lockf : file_descr -> lock_command -> int -> unit

lockf fd mode len 在以 fd 開啟的檔案的某個區域上設定鎖定。該區域從 fd 的目前讀/寫位置開始 (由 Unix.lseek 設定),如果 len 為正數,則向前延伸 len 個位元組;如果 len 為負數,則向後延伸 len 個位元組;如果 len 為零,則延伸至檔案末尾。寫入鎖定會防止任何其他程序取得該區域的讀取或寫入鎖定。讀取鎖定會防止任何其他程序取得該區域的寫入鎖定,但允許其他程序取得該區域的讀取鎖定。

F_LOCKF_TLOCK 命令嘗試在指定的區域上設定寫入鎖定。F_RLOCKF_TRLOCK 命令嘗試在指定的區域上設定讀取鎖定。如果其他程序設定的一或多個鎖定阻止目前程序取得鎖定,F_LOCKF_RLOCK 會封鎖直到這些鎖定被移除,而 F_TLOCKF_TRLOCK 會立即失敗並拋出例外狀況。F_ULOCK 會移除目前程序在指定區域上的任何鎖定。最後,F_TEST 命令會測試是否可以在指定區域上取得寫入鎖定,而不會實際設定鎖定。如果成功,它會立即返回;否則會失敗。

當一個程序嘗試鎖定一個已經被同一個程序鎖定的檔案區域時,會發生什麼情況取決於作業系統。在符合 POSIX 標準的系統上,第二個鎖定操作會成功,並且可能會將較舊的鎖定從讀取鎖定「升級」為寫入鎖定。在 Windows 上,第二個鎖定操作會封鎖或失敗。

訊號

注意:訊號處理常式的安裝是透過 Sys.signalSys.set_signal 函數執行的。

val kill : int -> int -> unit

kill pid signal 將訊號編號 signal 送至 ID 為 pid 的程序。

在 Windows 上:僅模擬 Sys.sigkill 訊號。

type sigprocmask_command = 
| SIG_SETMASK
| SIG_BLOCK
| SIG_UNBLOCK
val sigprocmask : sigprocmask_command -> int list -> int list

sigprocmask mode sigs 變更被封鎖訊號的集合。如果 modeSIG_SETMASK,則被封鎖的訊號會設定為清單 sigs 中的訊號。如果 modeSIG_BLOCK,則 sigs 中的訊號會新增至被封鎖訊號的集合。如果 modeSIG_UNBLOCK,則 sigs 中的訊號會從被封鎖訊號的集合中移除。sigprocmask 會傳回先前被封鎖的訊號集合。

當載入 Thread 模組的 systhreads 版本時,此函數會重新導向至 Thread.sigmask。也就是說,sigprocmask 僅變更目前執行緒的遮罩。

val sigpending : unit -> int list

傳回目前擱置的被封鎖訊號集合。

val sigsuspend : int list -> unit

sigsuspend sigs 會以原子方式將被封鎖的訊號設定為 sigs,並等待傳遞一個未被忽略且未被封鎖的訊號。返回時,被封鎖的訊號會重設為其初始值。

val pause : unit -> unit

等待直到傳遞一個未被忽略且未被封鎖的訊號。

時間函式

type process_times = {
   tms_utime : float; (*

程序的用戶時間

*)
   tms_stime : float; (*

程序的系統時間

*)
   tms_cutime : float; (*

子程序的用戶時間

*)
   tms_cstime : float; (*

子程序的系統時間

*)
}

程序的執行時間 (CPU 時間)。

type tm = {
   tm_sec : int; (*

秒 0..60

*)
   tm_min : int; (*

分 0..59

*)
   tm_hour : int; (*

時 0..23

*)
   tm_mday : int; (*

月份中的日期 1..31

*)
   tm_mon : int; (*

年份中的月份 0..11

*)
   tm_year : int; (*

年份 - 1900

*)
   tm_wday : int; (*

星期幾 (星期日為 0)

*)
   tm_yday : int; (*

年份中的日期 0..365

*)
   tm_isdst : bool; (*

是否生效日光節約時間

*)
}

表示牆上時鐘時間和日曆日期的類型。

val time : unit -> float

傳回自 1970 年 1 月 1 日 00:00:00 GMT 以來的目前時間 (以秒為單位)。

val gettimeofday : unit -> float

Unix.time 相同,但解析度優於 1 秒。

val gmtime : float -> tm

將由 Unix.time 傳回的以秒為單位時間轉換為日期和時間。假設為 UTC (協調世界時),也稱為 GMT。若要執行反向轉換,請將 TZ 環境變數設定為 "UTC",使用 Unix.mktime,然後還原 TZ 的原始值。

val localtime : float -> tm

將由 Unix.time 傳回的以秒為單位時間轉換為日期和時間。假設為當地時區。執行反向轉換的函數為 Unix.mktime

val mktime : tm -> float * tm

將由 tm 引數指定的日期和時間轉換為由 Unix.time 傳回的以秒為單位的時間。會忽略 tmtm_isdsttm_wdaytm_yday 欄位。也會傳回給定 tm 記錄的正規化複本,其中 tm_wdaytm_ydaytm_isdst 欄位會從其他欄位重新計算,而其他欄位則會正規化 (例如,將 40 October 變更為 9 November)。tm 引數會以當地時區解譯。

val alarm : int -> int

在指定的秒數後排程 SIGALRM 訊號。

val sleep : int -> unit

停止執行指定的秒數。

val sleepf : float -> unit

停止執行指定的秒數。與 sleep 類似,但支援秒的分數。

val times : unit -> process_times

傳回程序的執行時間。

在 Windows 上:部分實作,不會報告子程序的計時。

val utimes : string -> float -> float -> unit

設定檔案的上次存取時間 (第二個引數) 和上次修改時間 (第三個引數)。時間以自 1970 年 1 月 1 日 00:00:00 GMT 起的秒數表示。如果兩個時間都是 0.0,則存取和上次修改時間都會設定為目前時間。

type interval_timer = 
| ITIMER_REAL (*

以實際時間遞減,並在到期時傳送訊號 SIGALRM

*)
| ITIMER_VIRTUAL (*

以程序虛擬時間遞減,並在到期時傳送 SIGVTALRM

*)
| ITIMER_PROF (*

(用於分析) 在程序執行時以及系統代表程序執行時都會遞減;它會在到期時傳送 SIGPROF

*)

三種間隔計時器。

type interval_timer_status = {
   it_interval : float; (*

期間

*)
   it_value : float; (*

計時器的目前值

*)
}

描述間隔計時器狀態的類型

val getitimer : interval_timer -> interval_timer_status

傳回給定間隔計時器的目前狀態。

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 設定為零會使計時器在其下一次到期後停用。

使用者 ID、群組 ID

val getuid : unit -> int

傳回執行程序的用戶的用戶 ID。

在 Windows 上:一律傳回 1

val geteuid : unit -> int

傳回程序執行的有效用戶 ID。

在 Windows 上:一律傳回 1

val setuid : int -> unit

設定程序的實際用戶 ID 和有效用戶 ID。

val getgid : unit -> int

傳回執行程序的用戶的群組 ID。

在 Windows 上:一律傳回 1

val getegid : unit -> int

傳回程序執行的有效群組 ID。

在 Windows 上:一律傳回 1

val setgid : int -> unit

設定程序的實際群組 ID 和有效群組 ID。

val getgroups : unit -> int array

傳回執行程序的用戶所屬的群組清單。

在 Windows 上:一律傳回 [|1|]

val setgroups : int array -> unit

setgroups groups 設定呼叫程序的補充群組 ID。需要適當的權限。

val initgroups : string -> int -> unit

initgroups user group 透過讀取群組資料庫 /etc/group 並使用 user 所屬的所有群組來初始化群組存取清單。額外的群組 group 也會新增至清單。

type passwd_entry = {
   pw_name : string;
   pw_passwd : string;
   pw_uid : int;
   pw_gid : int;
   pw_gecos : string;
   pw_dir : string;
   pw_shell : string;
}

passwd 資料庫中的項目結構。

type group_entry = {
   gr_name : string;
   gr_passwd : string;
   gr_gid : int;
   gr_mem : string array;
}

groups 資料庫中的項目結構。

val getlogin : unit -> string

傳回執行程序的用戶的登入名稱。

val getpwnam : string -> passwd_entry

passwd 中尋找具有指定名稱的項目。

val getgrnam : string -> group_entry

在給定的群組名稱的 group 中尋找項目。

val getpwuid : int -> passwd_entry

在給定的使用者 ID 的 passwd 中尋找項目。

val getgrgid : int -> group_entry

在給定的群組 ID 的 group 中尋找項目。

網際網路位址

type inet_addr 

網際網路位址的抽象型別。

val inet_addr_of_string : string -> inet_addr

將網際網路位址的可列印表示法轉換為其內部表示法。對於 IPv4 位址,參數字串由 4 個以句點分隔的數字組成 (XXX.YYY.ZZZ.TTT);對於 IPv6 位址,則由最多 8 個以冒號分隔的數字組成。

val string_of_inet_addr : inet_addr -> string

返回給定網際網路位址的可列印表示法。有關可列印表示法的描述,請參閱 Unix.inet_addr_of_string

val inet_addr_any : inet_addr

一個特殊的 IPv4 位址,僅用於 bind,表示主機擁有的所有網際網路位址。

val inet_addr_loopback : inet_addr

一個特殊的 IPv4 位址,表示主機 (127.0.0.1)。

val inet6_addr_any : inet_addr

一個特殊的 IPv6 位址,僅用於 bind,表示主機擁有的所有網際網路位址。

val inet6_addr_loopback : inet_addr

一個特殊的 IPv6 位址,表示主機 (::1)。

val is_inet6_addr : inet_addr -> bool

判斷給定的 inet_addr 是否為 IPv6 位址。

套接字

type socket_domain = 
| PF_UNIX (*

Unix 網域

*)
| PF_INET (*

網際網路網域 (IPv4)

*)
| PF_INET6 (*

網際網路網域 (IPv6)

*)

socket 網域的型別。並非所有平台都支援 IPv6 socket (型別為 PF_INET6)。

在 Windows 上:Windows 10 1803 及更高版本自 4.14.0 起支援 PF_UNIX

type socket_type = 
| SOCK_STREAM (*

串流 socket

*)
| SOCK_DGRAM (*

資料包 socket

*)
| SOCK_RAW (*

原始 socket

*)
| SOCK_SEQPACKET (*

循序封包 socket

*)

socket 種類的型別,指定通訊的語意。SOCK_SEQPACKET 包含在此處是為了完整性,但很少被作業系統支援,且需要此程式庫中沒有的系統呼叫。

type sockaddr = 
| ADDR_UNIX of string
| ADDR_INET of inet_addr * int

socket 位址的型別。ADDR_UNIX name 是 Unix 網域中的 socket 位址;name 是檔案系統中的檔案名稱。ADDR_INET(addr,port) 是網際網路網域中的 socket 位址;addr 是機器的網際網路位址,而 port 是連接埠號碼。

val socket : ?cloexec:bool ->
socket_domain -> socket_type -> int -> file_descr

在給定的網域中建立一個新的 socket,並具有給定的種類。第三個參數是協定類型;0 選擇該種類的 socket 的預設協定。有關 cloexec 可選參數的文件,請參閱 Unix.set_close_on_exec

val domain_of_sockaddr : sockaddr -> socket_domain

返回適用於給定 socket 位址的 socket 網域。

val socketpair : ?cloexec:bool ->
socket_domain ->
socket_type -> int -> file_descr * file_descr

建立一對未命名的 socket,彼此連接。有關 cloexec 可選參數的文件,請參閱 Unix.set_close_on_exec

val accept : ?cloexec:bool -> file_descr -> file_descr * sockaddr

接受給定 socket 上的連線。返回的描述元是一個連接到用戶端的 socket;返回的位址是連線用戶端的位址。有關 cloexec 可選參數的文件,請參閱 Unix.set_close_on_exec

val bind : file_descr -> sockaddr -> unit

將 socket 繫結到一個位址。

val connect : file_descr -> sockaddr -> unit

將 socket 連線到一個位址。

val listen : file_descr -> int -> unit

設定 socket 以接收連線請求。整數參數是等待請求的最大數目。

type shutdown_command = 
| SHUTDOWN_RECEIVE (*

關閉以進行接收

*)
| SHUTDOWN_SEND (*

關閉以進行傳送

*)
| SHUTDOWN_ALL (*

全部關閉

*)

shutdown 的指令型別。

val shutdown : file_descr -> shutdown_command -> unit

關閉 socket 連線。第二個參數為 SHUTDOWN_SEND 時,會導致連線另一端的讀取返回檔案結束條件。SHUTDOWN_RECEIVE 會導致連線另一端的寫入返回關閉的管道條件 (SIGPIPE 訊號)。

val getsockname : file_descr -> sockaddr

返回給定 socket 的位址。

val getpeername : file_descr -> sockaddr

返回連線到給定 socket 的主機位址。

type msg_flag = 
| MSG_OOB
| MSG_DONTROUTE
| MSG_PEEK
val recv : file_descr -> bytes -> int -> int -> msg_flag list -> int

從已連線的 socket 接收資料。

val recvfrom : file_descr ->
bytes -> int -> int -> msg_flag list -> int * sockaddr

從未連線的 socket 接收資料。

val send : file_descr -> bytes -> int -> int -> msg_flag list -> int

透過已連線的 socket 傳送資料。

val send_substring : file_descr -> string -> int -> int -> msg_flag list -> int

send 相同,但從字串而非位元組序列取得資料。

val sendto : file_descr ->
bytes -> int -> int -> msg_flag list -> sockaddr -> int

透過未連線的 socket 傳送資料。

val sendto_substring : file_descr ->
string -> int -> int -> msg_flag list -> sockaddr -> int

sendto 相同,但從字串而非位元組序列取得資料。

套接字選項

type socket_bool_option = 
| SO_DEBUG (*

記錄偵錯資訊

*)
| SO_BROADCAST (*

允許傳送廣播訊息

*)
| SO_REUSEADDR (*

允許重複使用繫結的本機位址

*)
| SO_KEEPALIVE (*

保持連線活動

*)
| SO_DONTROUTE (*

繞過標準路由演算法

*)
| SO_OOBINLINE (*

將帶外資料留在行內

*)
| SO_ACCEPTCONN (*

回報是否已啟用 socket 監聽

*)
| TCP_NODELAY (*

控制 TCP socket 的 Nagle 演算法

*)
| IPV6_ONLY (*

禁止將 IPv6 socket 繫結到 IPv4 位址

*)
| SO_REUSEPORT (*

允許重複使用位址和連接埠繫結

*)

可以使用 Unix.getsockopt 查詢和使用 Unix.setsockopt 修改的 socket 選項。這些選項具有布林值 (true/false)。

type socket_int_option = 
| SO_SNDBUF (*

傳送緩衝區的大小

*)
| SO_RCVBUF (*

接收緩衝區的大小

*)
| SO_ERROR (*
已棄用。請改用 Unix.getsockopt_error。

已棄用。請改用 Unix.getsockopt_error

*)
| SO_TYPE (*

回報 socket 型別

*)
| SO_RCVLOWAT (*

輸入操作要處理的最小位元組數

*)
| SO_SNDLOWAT (*

輸出操作要處理的最小位元組數

*)

可以使用 Unix.getsockopt_int 查詢和使用 Unix.setsockopt_int 修改的 socket 選項。這些選項具有整數值。

type socket_optint_option = 
| SO_LINGER (*

在關閉的連線上是否有存在資料時,要暫留多久 (以秒為單位)

*)

可以使用 Unix.getsockopt_optint 查詢和使用 Unix.setsockopt_optint 修改的 socket 選項。這些選項的值的型別為 int option,其中 None 表示「已停用」。

type socket_float_option = 
| SO_RCVTIMEO (*

輸入操作的逾時

*)
| SO_SNDTIMEO (*

輸出操作的逾時

*)

可以使用 Unix.getsockopt_float 查詢和使用 Unix.setsockopt_float 修改的 socket 選項。這些選項具有浮點值,表示以秒為單位的時間。值 0 表示無限逾時。

val getsockopt : file_descr -> socket_bool_option -> bool

返回給定 socket 中布林值選項的目前狀態。

val setsockopt : file_descr -> socket_bool_option -> bool -> unit

在給定的 socket 中設定或清除布林值選項。

val getsockopt_int : file_descr -> socket_int_option -> int

對於整數值 socket 選項,與 Unix.getsockopt 相同。

val setsockopt_int : file_descr -> socket_int_option -> int -> unit

對於整數值 socket 選項,與 Unix.setsockopt 相同。

val getsockopt_optint : file_descr -> socket_optint_option -> int option

對於值為 int option 的 socket 選項,與 Unix.getsockopt 相同。

val setsockopt_optint : file_descr -> socket_optint_option -> int option -> unit

對於值為 int option 的 socket 選項,與 Unix.setsockopt 相同。

val getsockopt_float : file_descr -> socket_float_option -> float

對於值為浮點數的 socket 選項,與 Unix.getsockopt 相同。

val setsockopt_float : file_descr -> socket_float_option -> float -> unit

對於值為浮點數的 socket 選項,與 Unix.setsockopt 相同。

val getsockopt_error : file_descr -> error option

返回與給定 socket 相關聯的錯誤條件,並將其清除。

高階網路連線函式

val open_connection : sockaddr -> in_channel * out_channel

連線到給定位址的伺服器。返回一對連接到伺服器的緩衝通道。請記住,在適當的時間呼叫輸出通道上的 flush,以確保正確的同步。

open_connection 返回的兩個通道共享一個到 socket 的描述元。因此,當連線結束時,您應該呼叫輸出通道上的 close_out,這也會關閉底層的 socket。請勿呼叫輸入通道上的 close_in;它最終會被 GC 收集。

val shutdown_connection : in_channel -> unit

「關閉」使用 Unix.open_connection 建立的連線;也就是說,向讀取連線另一端的伺服器傳送檔案結束條件。這不會關閉 socket 和連線使用的通道。請參閱 Unix.open_connection,了解如何在連線結束後關閉它們。

val establish_server : (in_channel -> out_channel -> unit) -> sockaddr -> unit

在給定位址上建立伺服器。對於每個與連接到用戶端的兩個緩衝通道的連線,都會呼叫作為第一個參數給定的函式。為每個連線建立一個新程序。Unix.establish_server 函式永遠不會正常返回。

提供給函式的兩個通道共享一個到 socket 的描述元。此函式不需要關閉通道,因為當函式返回時會自動關閉。如果此函式偏好明確關閉,它應該使用 close_out 關閉輸出通道,並保持輸入通道不關閉,原因在 Unix.in_channel_of_descr 中說明。

主機與協定資料庫

type host_entry = {
   h_name : string;
   h_aliases : string array;
   h_addrtype : socket_domain;
   h_addr_list : inet_addr array;
}

hosts 資料庫中項目的結構。

type protocol_entry = {
   p_name : string;
   p_aliases : string array;
   p_proto : int;
}

protocols 資料庫中項目的結構。

type service_entry = {
   s_name : string;
   s_aliases : string array;
   s_port : int;
   s_proto : string;
}

services 資料庫中項目的結構。

val gethostname : unit -> string

返回本機主機的名稱。

val gethostbyname : string -> host_entry

hosts 中尋找具有給定名稱的條目。

val gethostbyaddr : inet_addr -> host_entry

hosts 中尋找具有給定地址的條目。

val getprotobyname : string -> protocol_entry

protocols 中尋找具有給定名稱的條目。

val getprotobynumber : int -> protocol_entry

protocols 中尋找具有給定協定號碼的條目。

val getservbyname : string -> string -> service_entry

services 中尋找具有給定名稱的條目。

val getservbyport : int -> string -> service_entry

services 中尋找具有給定服務號碼的條目。

type addr_info = {
   ai_family : socket_domain; (*

Socket 網域

*)
   ai_socktype : socket_type; (*

Socket 類型

*)
   ai_protocol : int; (*

Socket 協定號碼

*)
   ai_addr : sockaddr; (*

地址

*)
   ai_canonname : string; (*

標準主機名稱

*)
}

Unix.getaddrinfo 傳回的地址資訊。

type getaddrinfo_option = 
| AI_FAMILY of socket_domain (*

強制使用給定的 socket 網域

*)
| AI_SOCKTYPE of socket_type (*

強制使用給定的 socket 類型

*)
| AI_PROTOCOL of int (*

強制使用給定的協定

*)
| AI_NUMERICHOST (*

不呼叫名稱解析器,預期為數字 IP 位址

*)
| AI_CANONNAME (*

填入結果的 ai_canonname 欄位

*)
| AI_PASSIVE (*

設定位址為 ``any'' 位址,以搭配 Unix.bind 使用

*)

Unix.getaddrinfo 的選項。

val getaddrinfo : string -> string -> getaddrinfo_option list -> addr_info list

getaddrinfo host service opts 傳回描述適用於與給定主機和服務通訊的 socket 參數和位址的 Unix.addr_info 記錄列表。如果主機或服務名稱未知,或者 opts 中表達的約束無法滿足,則傳回空列表。

host 要嘛是主機名稱,要嘛是 IP 位址的字串表示形式。host 可以為空字串;在這種情況下,會使用 ``any'' 位址或 ``loopback'' 位址,取決於 opts 是否包含 AI_PASSIVEservice 要嘛是服務名稱,要嘛是連接埠號碼的字串表示形式。service 可以為空字串;在這種情況下,傳回的位址的連接埠欄位會設定為 0。opts 是一個可能為空的選項列表,允許呼叫者強制使用特定的 socket 網域(例如僅限 IPv6 或僅限 IPv4)或特定的 socket 類型(例如僅限 TCP 或僅限 UDP)。

type name_info = {
   ni_hostname : string; (*

主機名稱或 IP 位址

*)
   ni_service : string; (*

服務名稱或連接埠號碼

*)
}

Unix.getnameinfo 傳回的主機和服務資訊。

type getnameinfo_option = 
| NI_NOFQDN (*

不要限定本機主機名稱

*)
| NI_NUMERICHOST (*

永遠以 IP 位址形式傳回主機

*)
| NI_NAMEREQD (*

如果無法判斷主機名稱,則失敗

*)
| NI_NUMERICSERV (*

永遠以連接埠號碼形式傳回服務

*)
| NI_DGRAM (*

將服務視為基於 UDP 而非預設的 TCP

*)

Unix.getnameinfo 的選項。

val getnameinfo : sockaddr -> getnameinfo_option list -> name_info

getnameinfo addr opts 傳回對應於 socket 位址 addr 的主機名稱和服務名稱。opts 是一個可能為空的選項列表,用於控制如何取得這些名稱。

終端機介面

以下函數實作 POSIX 標準終端介面。它們提供非同步通訊埠和虛擬終端的控制。如需完整說明,請參閱 termios 手冊頁。

type 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; (*

在輸入字元上移除第 8 個位元。

*)
   mutable c_inlcr : bool; (*

將輸入的 NL 對應到 CR。

*)
   mutable c_igncr : bool; (*

忽略輸入的 CR。

*)
   mutable c_icrnl : bool; (*

將輸入的 CR 對應到 NL。

*)
   mutable c_ixon : bool; (*

辨識輸入的 XON/XOFF 字元。

*)
   mutable c_ixoff : bool; (*

發出 XON/XOFF 字元來控制輸入流量。

*)
   mutable c_opost : bool; (*

啟用輸出處理。

*)
   mutable c_obaud : int; (*

輸出傳輸速率 (0 表示關閉連線)。

*)
   mutable c_ibaud : int; (*

輸入傳輸速率。

*)
   mutable c_csize : int; (*

每個字元的位元數 (5-8)。

*)
   mutable c_cstopb : int; (*

停止位元數 (1-2)。

*)
   mutable c_cread : bool; (*

已啟用接收。

*)
   mutable c_parenb : bool; (*

啟用同位產生和偵測。

*)
   mutable c_parodd : bool; (*

指定奇同位而非偶同位。

*)
   mutable c_hupcl : bool; (*

在最後一次關閉時掛斷。

*)
   mutable c_clocal : bool; (*

忽略數據機狀態線。

*)
   mutable c_isig : bool; (*

在 INTR、QUIT、SUSP 時產生訊號。

*)
   mutable c_icanon : bool; (*

啟用標準處理 (行緩衝和編輯)

*)
   mutable c_noflsh : bool; (*

在 INTR、QUIT、SUSP 之後停用刷新。

*)
   mutable c_echo : bool; (*

回顯輸入字元。

*)
   mutable c_echoe : bool; (*

回顯 ERASE (以擦除先前的字元)。

*)
   mutable c_echok : bool; (*

回顯 KILL (以擦除目前的行)。

*)
   mutable c_echonl : bool; (*

即使未設定 c_echo,也會回顯 NL。

*)
   mutable c_vintr : char; (*

中斷字元 (通常為 ctrl-C)。

*)
   mutable c_vquit : char; (*

結束字元 (通常為 ctrl-\)。

*)
   mutable c_verase : char; (*

擦除字元 (通常為 DEL 或 ctrl-H)。

*)
   mutable c_vkill : char; (*

刪除行字元 (通常為 ctrl-U)。

*)
   mutable c_veof : char; (*

檔案結束字元 (通常為 ctrl-D)。

*)
   mutable c_veol : char; (*

替代的行尾字元。(通常為無)。

*)
   mutable c_vmin : int; (*

滿足讀取請求之前要讀取的最小字元數。

*)
   mutable c_vtime : int; (*

最大讀取等待時間 (以 0.1 秒為單位)。

*)
   mutable c_vstart : char; (*

開始字元 (通常為 ctrl-Q)。

*)
   mutable c_vstop : char; (*

停止字元 (通常為 ctrl-S)。

*)
}
val tcgetattr : file_descr -> terminal_io

傳回由給定檔案描述符參照的終端機的狀態。

type setattr_when = 
| TCSANOW
| TCSADRAIN
| TCSAFLUSH
val tcsetattr : file_descr -> setattr_when -> terminal_io -> unit

設定由給定檔案描述符參照的終端機的狀態。第二個引數表示狀態變更發生的時間:立即 (TCSANOW)、在所有擱置的輸出都已傳輸之後 (TCSADRAIN),或在刷新所有已接收但未讀取的輸入之後 (TCSAFLUSH)。建議在變更輸出參數時使用 TCSADRAIN;在變更輸入參數時使用 TCSAFLUSH

val tcsendbreak : file_descr -> int -> unit

在給定的檔案描述符上發送一個中斷條件。第二個參數是中斷的持續時間,以 0.1 秒為單位;0 表示標準持續時間 (0.25 秒)。

val tcdrain : file_descr -> unit

等待直到在給定的檔案描述符上寫入的所有輸出都已傳輸。

type flush_queue = 
| TCIFLUSH
| TCOFLUSH
| TCIOFLUSH
val tcflush : file_descr -> flush_queue -> unit

根據第二個參數,捨棄在給定的檔案描述符上寫入但尚未傳輸的資料,或已接收但尚未讀取的資料:TCIFLUSH 清除已接收但未讀取的資料,TCOFLUSH 清除已寫入但未傳輸的資料,而 TCIOFLUSH 則同時清除兩者。

type flow_action = 
| TCOOFF
| TCOON
| TCIOFF
| TCION
val tcflow : file_descr -> flow_action -> unit

根據第二個參數,暫停或重新啟動在給定檔案描述符上的資料接收或傳輸:TCOOFF 暫停輸出,TCOON 重新啟動輸出,TCIOFF 發送一個 STOP 字元以暫停輸入,而 TCION 發送一個 START 字元以重新啟動輸入。

val setsid : unit -> int

將呼叫的進程放入新的會話中,並將其從其控制終端分離。