Как я могу использовать popen, чтобы открыть «экран» в C ++? - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть программа на С ++:

#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 () ничего не вызывает.Я не уверен, правильно ли я это делаю.Есть идеи?Спасибо

1 Ответ

0 голосов
/ 19 ноября 2018

Вам необходимо подключить канал stdin вашего подпроцесса к реальному терминалу ... или, по крайней мере, к псевдотерминалу.Предполагая, что вы работаете в системе POSIX (судя по вашим тегам), вы можете использовать posix_openpt и ptsname, чтобы получить их.

Псевдокод(НЕ БЕЗОПАСНО ДЛЯ РЕЗЬБЫ):

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 см. этот прекрасный пост в блоге .По сути, он делает некоторую магию, заставляя исполняемый процесс использовать определенные файловые дескрипторы, которые затем могут быть прочитаны основной программой.

В качестве альтернативы, вы можете сделать небольшой хак (все еще НЕ БЕЗОПАСНЫЙ ДЛЯ THREAD):

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

Заменить pseudo_sprintf на реальный snprintf вызов и правильную буферизацию.

...