0

ねえ、うまくいけば、これが私の PTY 関連の最後の質問になるはずです。もっとエキサイティングな問題に移ることができます。(c;

pty の作成と読み書きのために私が書いた一連の小さな関数を次に示します。 http://pastebin.com/m4fcee34d 唯一の問題は、それらが機能しないことです。初期化子と writeToPty( "ls -l" ) を実行した後、readFromPty からの「出力」はまだ空です。

Ubuntu、QT C++

編集済み:わかりました、読み取りループを除いて、このすべてが機能することを確認できます。デバッガーの [locals/watchers] タブでは、QString の「出力」が実際に正しいデータを取得することを示していますが、その後 ( 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;
}

編集:これは、最終的に機能したコードを含む質問へのリンクです

4

1 に答える 1

2

私はposixに完全に精通していることに注意しますが、このページhttp://pwet.fr/man/linux/fonctions_bibliotheques/posix/readを読んだ後、私はいくつかの洞察を得ました。さらに、ループの最初のパスで期待したほど多くを読み取っていない場合、M_nBytes値を調整しているとは思えません。

編集:そのリンクから、おそらくこれはいくつかの助けになるでしょう:

一部のプロセスでパイプが書き込み用に開いていて、O_NONBLOCKがクリアされている場合、read()は、データが書き込まれるか、パイプが書き込み用に開いていたすべてのプロセスによってパイプが閉じられるまで、呼び出し元のスレッドをブロックします。

非ブロッキング読み取りをサポートし、現在利用可能なデータがないファイル(パイプまたはFIFO以外)を読み取ろうとした場合:

* O_NONBLOCKがクリアされている場合、read()は、一部のデータが使用可能になるまで呼び出し元のスレッドをブロックします。

つまり、基本的に、エラー状態ではなく、読み取りを続けるように指示すると、読み取るものが見つかるまでブロックされます。

于 2010-02-07T01:51:10.097 に答える