总结
向频道写入消息。
声明
#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()
类似,它会尝试向 handle 指定的通道写入一条包含 num_bytes 字节和 num_handles 句柄的消息,但此外,它将对正在传输的句柄执行操作,其中 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 用于验证调用方希望 handle 的对象类型。它可以是 ZX_OBJ_TYPE_NONE(用于跳过验证检查),也可以是 zx_obj_type_t
定义的类型之一。
应用于 handle 的操作之一是:
ZX_HANDLE_OP_MOVE
这相当于先发出zx_handle_replace()
,然后发出zx_channel_write()
。源句柄始终是闭合的。ZX_HANDLE_OP_DUPLICATE
这相当于先发出zx_handle_duplicate()
,然后发出zx_channel_write()
。来源句柄始终保持打开状态,可供调用方访问。
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_IOVEC
或 8192
zx_channel_iovec_t
个元素,所有 zx_channel_iovec_t
的 capacity
总和不超过 ZX_CHANNEL_MAX_MSG_BYTES
或 65536
个字节。buffer
不需要对齐,仅当 capacity
为零时,其才能为 NULL
。reserved
必须设置为零。
要么复制所有 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
handle 不是有效的句柄,handles 中的任何源句柄都不是有效句柄,或者在不存在 ZX_HANDLE_OP_DUPLICATE
标志的情况下,handles 数组中存在重复的句柄。
ZX_ERR_WRONG_TYPE
句柄不是通道句柄,或者 handles 中的任何源句柄均与对象类型 type 不匹配。
ZX_ERR_INVALID_ARGS
bytes 是无效的指针,handles 是无效的指针,或 options 为非零值,操作不是 ZX_HANDLE_OP_MOVE 或 ZX_HANDLE_OP_DUPLICATE 之一,或者 handles[i]->handle 中的任何源句柄都没有 whandle[i]->rights 中指定的权限。如果指定了 ZX_CHANNEL_WRITE_USE_IOVEC
选项,则当 buffer 字段包含无效指针或预留字段为非零时,将会生成 ZX_ERR_INVALID_ARGS
。
ZX_ERR_NOT_SUPPORTED
handle 包含在 handles 数组中。
ZX_ERR_ACCESS_DENIED
句柄没有 ZX_RIGHT_WRITE
,或者句柄中的任何源句柄都没有 ZX_RIGHT_TRANSFER
,或者句柄中的任何源句柄都没有 ZX_RIGHT_DUPLICATE
(如果指定了 ZX_HANDLE_OP_DUPLICATE
操作)。
ZX_ERR_PEER_CLOSED
通道的另一端已关闭。
ZX_ERR_NO_MEMORY
由于内存不足而失败。
用户空间没有什么方法来处理此(不太可能)错误。在以后的 build 中,此错误不会再发生。
ZX_ERR_OUT_OF_RANGE
num_bytes 或 num_handles 分别大于 ZX_CHANNEL_MAX_MSG_BYTES
或 ZX_CHANNEL_MAX_MSG_HANDLES
。如果指定了 ZX_CHANNEL_WRITE_USE_IOVEC
选项,则当 num_bytes 大于 ZX_CHANNEL_MAX_MSG_IOVEC
或 iovec 容量之和超过 ZX_CHANNEL_MAX_MSG_BYTES
时,会生成 ZX_ERR_OUT_OF_RANGE
。num_bytes
备注
如果调用方将 ZX_RIGHT_TRANSFER
移除到附加到消息的句柄,消息读取器将收到一个句柄,该句柄无法写入任何其他通道,但仍可以根据权限使用,并且可以在不需要时关闭。