【问题标题】:How do I use popen to open "screen" in C++?如何使用 popen 在 C++ 中打开“屏幕”?
【发布时间】:2019-04-22 03:39:47
【问题描述】:

我有一个 c++ 程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <fcntl.h>
using namespace std;



int main (int argc, const char * argv[]) {
//    system("script /dev/null");
    FILE *pout;
    pout = popen("screen tty.MobileRobot-RNI-SPP", "w");
    fprintf(pout,"hello");


    return 0;
}

问题是它会输出“必须连接到终端”。

然后该命令挂起。取消注释该 system() 调用不会导致任何事情发生。我不确定我是否做得正确。有任何想法吗?谢谢

【问题讨论】:

  • 在一般情况下,您需要将该进程的stdin 管道连接到实际终端,尽管可能有一种特定于屏幕的方式来执行此操作。
  • 在另一个程序中调用screen 似乎不寻常。你能解释一下你真正想要做什么吗?
  • 这似乎是XY problem。您要解决的实际问题是什么?
  • 不相关,但你说“我有一个 c++ 程序”.. 对 来说,你似乎有一个 C 程序。您发布的代码没有任何 C++(using namespace 位除外,但这无关紧要)。
  • @Brian 我需要从 tty 端口发送数据,但由于某些莫名其妙的原因,终端和 c++ 都无法正常工作。此外,屏幕工作。

标签: c++ linux macos popen gnu-screen


【解决方案1】:

您需要将子进程的stdin 管道连接到实际终端……或者至少是伪终端。假设您使用的是 POSIX 系统(根据您的标签判断),您可以使用 posix_openptptsname 来获取这些信息。

伪代码(非线程安全):

const int flags = O_RDWR;
int pseudouser = posix_openpt(flags);
int pseudoprog = open(ptsname(pseudouser), flags);

if (fork()) {
    execv magic with pseudoprog;
    exit(0);
}

FILE *pout = fdopen(pseudouser, "r+");
do stuff with pout

有关execv 魔法,请参阅this lovely blog post。基本上,它可以让执行的进程使用某些文件描述符,然后主程序可以读取这些文件描述符。

或者,您可以做一些小技巧(仍然不是线程安全的):

const int flags = O_RDWR;
int pseudouser = posix_openpt(flags);
char *pseudoname = ptsname(pseudouser);
FILE *pout = fdopen(pseudouser, "r+");

free(popen(pseudo_sprintf("screen tty.MobileRobot-RNI-SPP >\"%s\" 2>\"%s\" <\"%s\"", pseudoname, pseudoname, pseudoname)));

do stuff with pout

用真正的snprintf 调用和适当的缓冲替换pseudo_sprintf

【讨论】:

  • 我不明白。标准输入与此有什么关系?
  • @Bob Unix 非常以文件为中心。有些文件是伪终端。 screen 抱怨它连接到管道而不是伪终端,因此您可以将其连接到伪终端。
  • @Downvoter 对不起,为什么?如果您至少不告诉我这个非常好的答案有什么问题,我就无法改进。
  • 不是我。我也被否决了。但是我很困惑你怎么知道要使用 posix_openpt 打开哪个 tty 设备?您不应该指定设备名称吗?我的蓝牙模块叫做 tty.MobileRobot.. 例如
  • @Bob 该函数创建了一个新的虚拟终端对。
猜你喜欢
  • 2013-07-25
  • 2012-09-27
  • 2018-09-04
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多