Unix 方法来创建双向管道或任何类似的行为?

Unix way to create bi-directional pipes or anything which acts like that?

我需要一个基于双向文件系统(例如设备节点、命名套接字、命名管道等)的进程间通信可能性 Linux(可能还有其他 UNIX 系统) ), 假设类似于串行端口,即您可以为 read/write 打开 /dev/ttyS0 并且您可以使用 any 工具(包括普通 cat 命令)基本上,就我而言,另一部分不是硬件(串行端口),而是另一个但完全不相关的过程。是的,我已经阅读过关于 SO 的类似问题,但是我仍然不确定是否有 other 类似的解决方案,如果命名管道不适合我的需求。

我能看到的:

最好的方法是双向命名管道(一个进程写入它,另一个进程可以读取,反之亦然,如果它是半双工的,虽然问题不大),它适用于所有类 UNIX 系统,至少包括 Linux 和 OSX,但是我找不到任何像这样工作的东西。

我想要的是有一种方法来模拟(仅来自用户 space)类似串行端口的东西,这样我什至可以将它与一个简单的终端客户端一起使用(当然,ioctl 的设置up 串行参数不起作用,这不是问题!),或者我可以用 echo mmmmm > ...cat ... 简单地 write/read 它。我需要它,因为(计算机的)仿真器提供了类似于真机串行端口的东西,所以我可以通过它与仿真机进行交互。我不能使用其他工具(比如 socat 和使用命名套接字,甚至 TCP/IP 或其他工具)因为我还有一个我无法更改的封闭源客户端软件,它需要一个文件名作为"serial port device",但是我已经测试过它不会在各种串行端口相关的 ioctl() 调用上失败,幸运的是(它可以在命名管道上工作,只是单向性是我的问题),所以我需要解决"only"这个问题,它会解决的。

允许您在每个描述符上单独 read(2)write(2) 的唯一系统对象是套接字和 pty。这些是仅有的具有用于发送和接收数据的两个队列的对象。所有其他 pipe 东西只有一个,当你收到一对描述符(例如对于未命名的管道)时,如果你接下来阅读它,你写的内容将立即收到。

我不建议在这种情况下使用 pty 接口,因为正如你所说,在能够传输之前你必须做一些内务处理并且你必须处理设备参数(比如 termios 设备级别的配置、波特率和字符解释)

getsocketpair(3) 是一个库函数,它已经为您提供了一对 已连接的套接字 ,并允许您指定套接字的类型(网络套接字、unix 套接字等)你喜欢的来电。

int res, sfds[2];
res = getsocketpair(PF_LOCAL, SOCK_STREAM, 0, sfds);

将 return 0 如果成功并且 sfds 数组中有两个已连接的套接字。在 BSD 系统中(如 OS/X 派生自),getsocketpair(2) 是一个系统调用,它允许内核 select 一个没有开销的高效版本(如示例所示)由网络协议强加。

注意

正如您在评论中所说,您的程序很可能不仅执行 read(2)write(2) 调用,而且还是一个从用户那里获取原始输入的程序(比如切换无回声获取密码或获取 raw 输入作为交互式程序的模式,例如 vi(1)emacs(1) do)

在那种情况下,我建议您下载我的程序 slowtty 并研究和修改它以适合您。它正是你想要的。它分配一对 pty 并执行 input/output。它还要求您使用 tty 线路,但这只是因为它将终端设置从您的 stdin 复制到 pty 线路。这是一个简单的程序,旨在教人们如何使用 pty(7) 界面,它在 FreeBSD、Mac/OS X 和 linux 中运行良好。因此,程序将 tty input/output 减慢到从属 pty 中调整的波特率,因此它允许您查看输出,就好像您在使用旧的串行 tty 线路一样。减速是在一个单独的例程中进行的,因此可以很容易地从源代码中删除。