zx_channel_write_etc

摘要

撰寫訊息給管道。

宣告

#include <zircon/syscalls.h>

zx_status_t zx_channel_write_etc(zx_handle_t handle,
                                 uint32_t options,
                                 const void* bytes,
                                 uint32_t num_bytes,
                                 zx_handle_disposition_t* handles,
                                 uint32_t num_handles);

說明

zx_channel_write() 一樣,系統會嘗試將 num_bytes 位元組數和 num_handles 控點的訊息寫入 控點 指定的管道,但除此之外,也會針對傳輸的控點執行運算,其中所轉移的控點為 zx_handle_disposition_t 的陣列:

typedef struct zx_handle_disposition {
    zx_handle_op_t operation;
    zx_handle_t handle;
    zx_obj_type_t type;
    zx_rights_t rights;
    zx_status_t result;
} zx_handle_disposition_t;

在 zx_handle_disposition_t 中,「handle」是要操作的來源控點,「rights」是所需的最終權限 (而非遮罩),且「result」必須設為 ZX_OK。所有來源帳號代碼都必須含有 ZX_RIGHT_TRANSFER,但也可在「權利」中移除,這樣訊息接收器就無法提供這項資訊。

type 是用來驗證呼叫端「處理」物件類型的物件類型。您可以 ZX_OBJ_TYPE_NONE 略過驗證檢查,也可以是 zx_obj_type_t 定義的類型之一。

套用至 handle 的作業為下列其中一項:

帳號代碼將具備能力」 (可以是 ZX_RIGHT_SAME_RIGHTS 或有限的權利組合) 或 ZX_RIGHT_NONE。此外,這項作業也允許在權利中移除 ZX_RIGHT_TRANSFER,讓接收器無法使用這項能力。

如果有任何作業失敗,該來源控制代碼的錯誤代碼會寫入 result,而 zx_channel_write_etc() 的傳回值中會顯示首次失敗。即使一或多個作業失敗,系統仍會嘗試 handles 陣列中的所有作業。

每個項目的所有作業都必須成功寫入訊息。成功後,帳號代碼會附加至訊息,並從管道端提供給該訊息的讀者。

如果在 handles 陣列 (訊息中傳送的控點) 中加入 handle (寫入目標管道的帳號代碼),是無效做法。

可以在訊息中傳送的帳號代碼數量上限為 ZX_CHANNEL_MAX_MSG_HANDLES,也就是 64。

訊息中可傳送的位元組數量上限為 ZX_CHANNEL_MAX_MSG_BYTES,也就是 65536。

zx_channel_read()zx_channel_read_etc() 會清空訊息。如未及時清空訊息,可能會導致使用過多核心記憶體,這可能會產生例外狀況。詳情請參閱 ipc 限制

ZX_CHANNEL_WRITE_USE_IOVEC 選項

如果指定 ZX_CHANNEL_WRITE_USE_IOVEC 選項,系統會將 bytes 解讀為 zx_channel_iovec_t 陣列,並指定要依序複製到訊息的位元組切片。num_bytes 會指定 bytes 中的 zx_channel_iovec_t 陣列元素數量。

typedef struct zx_channel_iovec {
  const void* buffer;      // User-space bytes.
  uint32_t capacity;       // Number of bytes.
  uint32_t reserved;       // Reserved.
} zx_channel_iovec_t;

bytes 陣列最多只能有 ZX_CHANNEL_MAX_MSG_IOVEC8192 zx_channel_iovec_t 個元素,且所有 zx_channel_iovec_t 的總和為 capacity,且不超過 ZX_CHANNEL_MAX_MSG_BYTES65536 位元組。buffer 不必對齊,而如果 capacity 為零,則只能設為 NULLreserved 必須設為 0。

系統只會複製所有 zx_channel_iovec_t 並傳送訊息,或是不會複製訊息,因此不會傳送訊息。使用傳送帳號代碼的方式維持不變。

權限

handle 必須是 ZX_OBJ_TYPE_CHANNEL 類型,且具有 ZX_RIGHT_WRITE

每個帳號代碼的項目都必須包含 ZX_RIGHT_TRANSFER

傳回值

zx_channel_write_etc() 會在成功時傳回 ZX_OK

錯誤

ZX_ERR_BAD_HANDLE 處理常式不是有效的控制代碼,處理常式中的任何來源控點都不是有效的控制代碼,或者如果 ZX_HANDLE_OP_DUPLICATE 標記不存在,處理常式陣列中會有重複的控點。

ZX_ERR_WRONG_TYPE 處理常式不是管道控制代碼,或者處理常式中的任何來源控點都與物件類型「類型」不符。

ZX_ERR_INVALID_ARGS bytes 是無效指標、處理常式為無效指標、選項為非零;或運算並非 ZX_HANDLE_OP_MOVE 或 ZX_HANDLE_OP_DUPLICATE 的任一種,或是 Whandles[i]->handle 中的任何來源帳號代碼。如果指定 ZX_CHANNEL_WRITE_USE_IOVEC 選項,如果 buffer 欄位包含無效指標,或保留欄位不是零,就會產生 ZX_ERR_INVALID_ARGS

ZX_ERR_NOT_SUPPORTED 處理常式包含在處理常式陣列中。

ZX_ERR_ACCESS_DENIED 處理常式中沒有 ZX_RIGHT_WRITE,或處理常式中的任何來源控點都沒有 ZX_RIGHT_TRANSFER,或者當指定 ZX_HANDLE_OP_DUPLICATE 作業時,帳號代碼中的任何來源控點都沒有 ZX_RIGHT_DUPLICATE

ZX_ERR_PEER_CLOSED 管道另一側已關閉。

ZX_ERR_NO_MEMORY 因記憶體不足而失敗。使用者空間無法以任何方式處理這個錯誤 (極可能) 錯誤。日後的建構作業不會再發生這個錯誤。

ZX_ERR_OUT_OF_RANGE num_bytesnum_handles 大於 ZX_CHANNEL_MAX_MSG_BYTESZX_CHANNEL_MAX_MSG_HANDLES。如果指定 ZX_CHANNEL_WRITE_USE_IOVEC 選項,如果 num_bytes 大於 ZX_CHANNEL_MAX_MSG_IOVEC,或生物容量總和超過 ZX_CHANNEL_MAX_MSG_BYTES,就會產生 ZX_ERR_OUT_OF_RANGE

附註

如果呼叫端將 ZX_RIGHT_TRANSFER 移除到訊息附加的控制代碼,則訊息讀取器會收到無法寫入任何其他管道的控制代碼,但仍可根據其權利使用,且可視需要關閉。

另請參閱