这是我为pty创建和读/写而编写的一组小函数:http://pastebin.com/m4fcee34d唯一的问题是它们不起作用!运行初始化程序和writeToPty(“ls -l”)后,readFromPty的'output'仍为空。
Ubuntu,QT C ++
编辑:好的,我可以确认所有这些东西都有效,除了读取循环。在调试器的locals / watchers选项卡中,它显示QString'output'实际上确实获得了正确的数据,但在它之后(read())运行的字符用完了它然后挂起。发生了什么,我该如何解决? 谢谢! (C:
#include <iostream>
#include <unistd.h>
#include <utmp.h>
#include <pty.h>
#include <QString>
#include <QThread>
// You also need libutil in your .pro file for this to compile.
class CMkPty
{
public:
CMkPty( int *writeChannel, int *readChannel );
~CMkPty();
int runInPty( char *command );
int writeToPty( char *input );
int readFromPty( QString output );
int m_nPid;
private:
int m_nMaster, m_nSlave, m_nPosition, m_nBytes;
char *m_chName;
void safe_print( char *s );
char m_output;
};
CMkPty::CMkPty( int *masterFD, int *slaveFD )
{
openpty( &m_nMaster, &m_nSlave, (char*)0, __null, __null );
m_nPid = fork();
*masterFD = m_nMaster;
*slaveFD = m_nSlave;
if( m_nPid == 0 )
{
login_tty( m_nSlave );
execl( "/bin/bash", "-l", (char*)0 );
return;
}
else if( m_nPid > 0 )
{
return;
}
else if( m_nPid < 0 )
{
std::cout << "Failed to fork." ;
return;
}
}
CMkPty::~CMkPty()
{
close( m_nMaster );
close( m_nSlave );
}
int CMkPty::writeToPty( char *szInput )
{
int nWriteTest;
write( m_nMaster, szInput, sizeof( szInput ) );
nWriteTest = write( m_nMaster, "\n", 1 );
if( nWriteTest < 0 )
{
std::cout << "Write to PTY failed" ;
return -1;
}
return 0;
}
int CMkPty::readFromPty( QString output )
{
char buffer[ 160 ];
m_nBytes = sizeof( buffer );
while ( ( m_nPosition = read( m_nMaster, buffer, m_nBytes ) ) > 0 )
{
buffer[ m_nPosition ] = 0;
output += buffer;
}
return 0;
}
编辑:Here是一个问题的链接,其中包含最终适合我的代码。
答案 0 :(得分:2)
我注意到完全熟悉posix,但在阅读本页http://pwet.fr/man/linux/fonctions_bibliotheques/posix/read后,我有了一些见解。更重要的是,如果你没有读到你在循环的第一遍中所期望的那么多,我没有看到你调整你的M_nBytes值。
编辑:从该链接开始,也许这会有所帮助:
如果某个进程打开了管道并且O_NONBLOCK已清除,则read()将阻塞调用线程,直到写入一些数据或管道被管道打开以供写入的所有进程关闭。
尝试读取支持非阻塞读取且当前没有可用数据的文件(管道或FIFO除外)时:
* 如果O_NONBLOCK清零,read()将阻塞调用线程,直到某些数据可用。
所以基本上,如果你没有处于错误状态,并且你告诉它继续阅读,它会阻塞,直到找到要读的东西。