1

以下更改将 nethack nacl 端口从使用 nacl-mounts 更新为 nacl_io。在 nacl-mounts 版本中,JSPipeMount 用于将来自浏览器的消息汇集到 nacl 程序的标准输入中。在 nacl_io 版本中是如何实现的?

https://chromium.googlesource.com/external/naclports/+/8ac229a6e3fddff3e061017a8eb85105874570b3%5E!/

4

1 回答 1

4

如提交描述中所述:“浏览器和 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”读取来读取
  • 对“/dev/tty”的写入被转换为对pp::Instance::PostMessage.
  • 如果要将 stdin 和 stdout 映射到 /dev/tty,可以将PS_STDINandPS_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,或者从该库中复制行为。

于 2013-10-14T16:01:22.683 回答