Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在不修改程序的情况下从标准输出捕获无缓冲输出?_C_Linux_Pty - Fatal编程技术网

C 如何在不修改程序的情况下从标准输出捕获无缓冲输出?

C 如何在不修改程序的情况下从标准输出捕获无缓冲输出?,c,linux,pty,C,Linux,Pty,我正在编写一个用于运行程序的实用程序,需要从程序中捕获无缓冲的stdout和stderr。我需要: 捕获stdout和stderr以分离文件 输出不需要缓冲(或行缓冲) 不修改正在运行的程序的源 问题是,当管道输出到文件时,标准输出流变成块缓冲而不是行缓冲。如果程序崩溃,输出永远不会刷新,并且为空。因此,我需要在不使用缓冲(或使用行缓冲)的情况下捕获标准输出 我认为这可以通过pty来实现,但我很难找到任何完全符合我要求的示例(大多数忽略了stderr)。事实上,我不确定我是否在C中找到了任何

我正在编写一个用于运行程序的实用程序,需要从程序中捕获无缓冲的stdout和stderr。我需要:

  • 捕获stdout和stderr以分离文件
  • 输出不需要缓冲(或行缓冲)
  • 不修改正在运行的程序的源
问题是,当管道输出到文件时,标准输出流变成块缓冲而不是行缓冲。如果程序崩溃,输出永远不会刷新,并且为空。因此,我需要在不使用缓冲(或使用行缓冲)的情况下捕获标准输出

我认为这可以通过pty来实现,但我很难找到任何完全符合我要求的示例(大多数忽略了stderr)。事实上,我不确定我是否在C中找到了任何pty示例;大多数使用更高级别的接口,如Python的pty和子流程模块

有人能帮忙吗(代码片段或链接)?任何帮助都将不胜感激

编辑:我想我已经解决了。以下两个链接非常有用

我的代码作为存储库提供:

参见
man 7 pty

特别是:

Unix 98伪终端 通过调用打开未使用的Unix 98伪终端主机
posix\u openpt(3)
。(此功能打开主克隆设备,
/dev/ptmx
;执行任何特定于程序的初始化后,请参阅
pts(4)
, 更改从属设备的所有权和权限 使用
grantpt(3)
,并使用
unlockt(3)
)解锁从机,相应的 通过传递返回的名称可以打开从属设备
ptsname(3)
调用
open(2)

现在您已经知道了这种代码需要调用的库函数的名称,您可以做两件有用的事情:

  • 查阅他们的手册页
  • 例如谷歌代码。既然你知道搜索引擎应该使用什么关键词,我想你会有更多的运气去寻找例子

请注意,posix_openpt()和相关函数是posix的最新添加,目前还没有广泛使用。具体来说,MacOS X上不提供(无论如何,10.5版)。OTOH,它们似乎在Solaris 10上可用。对于Linux来说,它们可能会大大简化生活。这一点很好。BSD风格的pty虽然在linux文档中被视为非标准,但实际上可能是事实上的标准。对我来说没关系!我选择了普通的linux方法,因为他的问题被标记为“linux”。在将slavefd复制到stdin/stdout/stderr之后,您应该看看是否应该关闭slavefd……您可能应该这样做,但似乎没有这样做。还考虑家长是否应该退出孩子的状态-担心如何处理信号。目前,调用代码只能通过查看数据来发现。此外,您还应确保当无法执行execv()时,子级返回非零状态-此时,它返回0.0。我添加了execv错误的捕获。对于dup2,似乎已经包含close调用(请参阅)。如果目标文件描述符处于打开状态,dup2()将关闭该描述符;但是,通常需要在dup2()完成后关闭源文件描述符。也就是说,如果pty是在文件描述符8上打开的,那么将2复制到1,那么您希望在将副本设置为1后关闭8。否则,当您执行exec()时,子项将打开描述符0、1、2和8,以及任何其他偏移。