Unsolved Using QIODevice with anonymous pipes
-
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?
-
@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 theQFile
.
And lastly,QFile
is a random access device, while a pipe is not, so weird behavior isn't unexpected. -
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. -
@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_7ChannelEE.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.
-
Maybe, I don't know which example you mean.
Found it:
https://doc.qt.io/qt-5/qfile.html#open-1But 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!