以下更改将 nethack nacl 端口从使用 nacl-mounts 更新为 nacl_io。在 nacl-mounts 版本中,JSPipeMount 用于将来自浏览器的消息汇集到 nacl 程序的标准输入中。在 nacl_io 版本中是如何实现的?
https://chromium.googlesource.com/external/naclports/+/8ac229a6e3fddff3e061017a8eb85105874570b3%5E!/
以下更改将 nethack nacl 端口从使用 nacl-mounts 更新为 nacl_io。在 nacl-mounts 版本中,JSPipeMount 用于将来自浏览器的消息汇集到 nacl 程序的标准输入中。在 nacl_io 版本中是如何实现的?
https://chromium.googlesource.com/external/naclports/+/8ac229a6e3fddff3e061017a8eb85105874570b3%5E!/
如提交描述中所述:“浏览器和 nexe 之间的通信由 TtyNode 使用 Pepper Simple 处理。”
我在这里回答了有关本地客户端讨论 Google 组的更多详细信息:https ://groups.google.com/d/msg/native-client-discuss/nOKHWBhBPfs/i_gUYIFuBJAJ
以下是那篇帖子的内容:
在 nacl_io 中,这只是一个节点 ( MountNodeTty
),而不是新的挂载。您可以通过打开文件“/dev/tty”来访问它。
最简单的使用方法是使用“ppapi_simple”库。它执行以下操作:
pp::Instance::HandleMessage
数据转发到节点,然后可以通过从“/dev/tty”读取来读取pp::Instance::PostMessage
.如果要将 stdin 和 stdout 映射到 /dev/tty,可以将PS_STDIN
andPS_STDOUT
参数设置为“/dev/tty”。您可以通过向嵌入标签添加其他属性来做到这一点:
<embed src="..." type="application/x-pnacl" PS_STDIN="/dev/tty" PS_STDOUT=/dev/tty"...>
要自己做,你必须做 ppapi_simple 库所做的事情。基本上,要将数据输入节点,您可以调用 ioctl:
这是来自 pepper_30 (src/ppapi_simple/ps_instance.cc:328) 的代码。pepper_32 的代码类似。
struct tioc_nacl_input_string ioctl_message;
ioctl_message.length = message_len;
ioctl_message.buffer = message_str.data();
int ret =
ioctl(fd_tty_, TIOCNACLINPUT, reinterpret_cast<char*>(&ioctl_message));
要在pp::Instance::PostMessage
写入时调用节点,请使用对 ioctl 的不同调用:
在pepper_30 中,这是自动完成的。但是,所有消息都带有前缀,因此您可以区分它们。这可以使用 ioctl (src/ppapi_simple/ps_instance.cc:210) 进行设置:
const char* tty_prefix = getenv("PS_TTY_PREFIX");
if (tty_prefix) {
fd_tty_ = open("/dev/tty", O_WRONLY);
if (fd_tty_ >= 0) {
ioctl(fd_tty_, TIOCNACLPREFIX, const_cast<char*>(tty_prefix));
} else {
Error("Failed to open /dev/tty.\n");
}
}
在 pepper_31 及更高版本中,您必须为 tty 节点显式设置回调函数。您可以使用第三个 ioctl (src/ppapi_simple/ps_instance.cc:221) 来做到这一点:
tioc_nacl_output handler;
handler.handler = TtyOutputHandlerStatic;
handler.user_data = this;
ioctl(tty_fd_, TIOCNACLOUTPUT, reinterpret_cast<char*>(&handler));
最后,如果您想将 stdin/stdout 重新映射到 /dev/tty,您也必须手动执行此操作。这就是 ppapi_simple 的工作方式(src/ppapi_simple/ps_instance:201):
int fd0 = open(getenv("PS_STDIN"), O_RDONLY);
dup2(fd0, 0);
int fd1 = open(getenv("PS_STDOUT"), O_WRONLY);
dup2(fd1, 1);
同样,实现这一点的最简单方法是使用 ppapi_simple,或者从该库中复制行为。