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
Qt 6.11 is out! See what's new in the release blog

Using QIODevice with anonymous pipes

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 2.3k 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