如提交描述中所述:
“浏览器和nexte之间的通信由使用Pepper Simple的TtyNode处理。”
我在这里回答了同样的问题,并详细介绍了本地客户端讨论谷歌小组:
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_STDIN
和
PS_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_22的代码类似。
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::实例::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_sample就是这样做的(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,或者从该库复制行为。