Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Using QIODevice with anonymous pipes
Forum Updated to NodeBB v4.3 + New Features

Using QIODevice with anonymous pipes

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 1.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sweepi
    wrote on last edited by
    #1

    I want to use a QIODevice in order to read from a unnamed pipe if data is available.
    I tried this with QFile:

    m_pFile_Pipe = new QFile();
    HANDLE hRead, hWrite;
    connect(m_pFile_Pipe, SIGNAL(readyRead()), this, SLOT(OutputAvailable_QFile()));
    
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    
    CreatePipe(&hRead, &hWrite, &sa, 0);
    auto fhRead = _open_osfhandle((intptr_t)hRead, _O_RDONLY);
    auto OpenResult = m_pFile_Pipe->open(fhRead, QIODevice::ReadOnly);
    

    The "raw" pipe itself works, I can read data from it.
    However, readyRead() is never signaled and during testing:

    void TestPipe() {
        char acBuffer[128];
        DWORD NumBytesRead;
        
        auto NumBytes = m_pFile_Pipe->bytesAvailable();
        qDebug() << "NumBytes" << NumBytes;
        ReadFile(hRead, acBuffer, sizeof(acBuffer), &NumBytesRead, NULL);
        qDebug() << QString::fromUtf8(acBuffer);
        while (m_pFile_Pipe->canReadLine()) {
            auto out = m_pFile_Pipe->readLine(512);
            qDebug() << "Line: " << out;
        }
        auto out_all = m_pFile_Pipe->readAll();
        qDebug() << "Raw: " << out_all;
    }
    

    NumBytes was always 0, canReadLine() always returned false, and readAll() did not return.
    ReadFile() could read the expected data.

    Is there a QOIDevice to use for anonymous pipes?

    kshegunovK 1 Reply Last reply
    0
    • S Sweepi

      I want to use a QIODevice in order to read from a unnamed pipe if data is available.
      I tried this with QFile:

      m_pFile_Pipe = new QFile();
      HANDLE hRead, hWrite;
      connect(m_pFile_Pipe, SIGNAL(readyRead()), this, SLOT(OutputAvailable_QFile()));
      
      SECURITY_ATTRIBUTES sa;
      sa.nLength = sizeof(SECURITY_ATTRIBUTES);
      sa.lpSecurityDescriptor = NULL;
      sa.bInheritHandle = TRUE;
      
      CreatePipe(&hRead, &hWrite, &sa, 0);
      auto fhRead = _open_osfhandle((intptr_t)hRead, _O_RDONLY);
      auto OpenResult = m_pFile_Pipe->open(fhRead, QIODevice::ReadOnly);
      

      The "raw" pipe itself works, I can read data from it.
      However, readyRead() is never signaled and during testing:

      void TestPipe() {
          char acBuffer[128];
          DWORD NumBytesRead;
          
          auto NumBytes = m_pFile_Pipe->bytesAvailable();
          qDebug() << "NumBytes" << NumBytes;
          ReadFile(hRead, acBuffer, sizeof(acBuffer), &NumBytesRead, NULL);
          qDebug() << QString::fromUtf8(acBuffer);
          while (m_pFile_Pipe->canReadLine()) {
              auto out = m_pFile_Pipe->readLine(512);
              qDebug() << "Line: " << out;
          }
          auto out_all = m_pFile_Pipe->readAll();
          qDebug() << "Raw: " << out_all;
      }
      

      NumBytes was always 0, canReadLine() always returned false, and readAll() did not return.
      ReadFile() could read the expected data.

      Is there a QOIDevice to use for anonymous pipes?

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      @Sweepi said in Using QIODevice with anonymous pipes:

      Is there a QOIDevice to use for anonymous pipes?

      I don't believe so. Probably cleanest is to implement your own QIODevice. However there are questions about the code you posted.

      For one what is OpenResult's value? I wouldn't expect the file to be opened multiple times successfully.
      And secondly, in your test code you don't spin the event loop so I see no reason to expect any signals to be emitted from the QFile.
      And lastly, QFile is a random access device, while a pipe is not, so weird behavior isn't unexpected.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      1
      • S Offline
        S Offline
        Sweepi
        wrote on last edited by Sweepi
        #3

        @kshegunov

        OpenResult was always true.
        However, since you mentioned that QFile and the pipe handle is a mismatch, I guess this does not mean too much.

        I stripped the code (in the starting post) down a little bit (since it contained unrelated "noise"), the event loop was working in my actual code, e.g. TestPipe() was called from a timer.

        Probably cleanest is to implement your own QIODevice.

        Can you point me to sth. similar where I can get ideas?
        E.g. I have no concept of how I would know that there is data available but to "poll" the pipe, which seems wrong.

        And lastly, QFile is a random access device, while a pipe is not, so weird behavior isn't unexpected.

        Actually, I have a follow-up question for this one:
        stderr etc. are also sequential devices, aren't they?
        I am wondering, because I remember an Qt example to open stderr using QFile.

        kshegunovK 1 Reply Last reply
        0
        • S Sweepi

          @kshegunov

          OpenResult was always true.
          However, since you mentioned that QFile and the pipe handle is a mismatch, I guess this does not mean too much.

          I stripped the code (in the starting post) down a little bit (since it contained unrelated "noise"), the event loop was working in my actual code, e.g. TestPipe() was called from a timer.

          Probably cleanest is to implement your own QIODevice.

          Can you point me to sth. similar where I can get ideas?
          E.g. I have no concept of how I would know that there is data available but to "poll" the pipe, which seems wrong.

          And lastly, QFile is a random access device, while a pipe is not, so weird behavior isn't unexpected.

          Actually, I have a follow-up question for this one:
          stderr etc. are also sequential devices, aren't they?
          I am wondering, because I remember an Qt example to open stderr using QFile.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @Sweepi said in Using QIODevice with anonymous pipes:

          Can you point me to sth. similar where I can get ideas?

          Any of the socket classes, or QProcess's stream reading/writing should be sufficient to get you started. For example, take a look here https://code.woboq.org/qt5/qtbase/src/corelib/io/qprocess.cpp.html#_ZN15QProcessPrivate18tryReadFromChannelEPNS_7ChannelE

          E.g. I have no concept of how I would know that there is data available but to "poll" the pipe, which seems wrong.

          You should try with QSocketNotifier.

          stderr etc. are also a sequential devices, aren't they?

          Yes.

          I am wondering, because I remember an Qt example to open stderr using QFile.

          Maybe, I don't know which example you mean. I open the standard streams through QTextStream directly, like this:

          QTextStream out(stdout);
          

          However I haven't checked what's the underlying code. Maybe you could check that too, I'd be interested to know as well.

          Read and abide by the Qt Code of Conduct

          S 1 Reply Last reply
          1
          • kshegunovK kshegunov

            @Sweepi said in Using QIODevice with anonymous pipes:

            Can you point me to sth. similar where I can get ideas?

            Any of the socket classes, or QProcess's stream reading/writing should be sufficient to get you started. For example, take a look here https://code.woboq.org/qt5/qtbase/src/corelib/io/qprocess.cpp.html#_ZN15QProcessPrivate18tryReadFromChannelEPNS_7ChannelE

            E.g. I have no concept of how I would know that there is data available but to "poll" the pipe, which seems wrong.

            You should try with QSocketNotifier.

            stderr etc. are also a sequential devices, aren't they?

            Yes.

            I am wondering, because I remember an Qt example to open stderr using QFile.

            Maybe, I don't know which example you mean. I open the standard streams through QTextStream directly, like this:

            QTextStream out(stdout);
            

            However I haven't checked what's the underlying code. Maybe you could check that too, I'd be interested to know as well.

            S Offline
            S Offline
            Sweepi
            wrote on last edited by
            #5

            @kshegunov

            Maybe, I don't know which example you mean.

            Found it:
            https://doc.qt.io/qt-5/qfile.html#open-1

            But maybe this is different since stderr is opened with QIODevice::WriteOnly, so there is no random access possible anyway.

            Thanks for all the hints, going to dig through this now!

            1 Reply Last reply
            1

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved