NmedPipe read(...) problems in Linux


#1

I’m using NamedPipe in Windows and in Linux application.
Windows version works fine, Linux version does not. I compared native implementation in juce_win_Files.cpp and juce_posix_NamedPipe.cpp files. Windows version returns if ReadFile reads anything, Linux version does not and tries to read whole buffer.
Because of this different behavior I believe Linux implementation is not correct.

Here is my Linux implementation that works same way as Windows does:
(juce_posix_NamedPipe.cpp)

int read (char* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
{
    auto timeoutEnd = getTimeoutEnd (timeOutMilliseconds);

    if (pipeIn == -1)
    {
        pipeIn = openPipe (createdPipe ? pipeInName : pipeOutName, O_RDONLY | O_NONBLOCK, timeoutEnd);

        if (pipeIn == -1)
			return -1;
    }
	if (maxBytesToRead <= 0)
		return 0;

	while (true)
	{
		auto numRead = (int) ::read (pipeIn, destBuffer, (size_t) maxBytesToRead);

		if (numRead > 0)
			return numRead;

		if (errno != EWOULDBLOCK || stopReadOperation.load() || hasExpired (timeoutEnd))
			return -1;

		const int maxWaitingTime = 30;
		waitForInput (pipeIn, timeoutEnd == 0 ? maxWaitingTime : jmin (maxWaitingTime, (int) (timeoutEnd - Time::getMillisecondCounter())));
    }
    return -1;
}

#2

Tom made a bunch of changes to NamedPipe a few days ago - have you checked the very latest version?


#3

I checked it but my issue is not fixed. Linux and Windows versions still behave differently.
This is my fix for latest version.

int read (char* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
{
	auto timeoutEnd = getTimeoutEnd(timeOutMilliseconds);

	if (maxBytesToRead <= 0)
		return 0;

	while (true)
	{
		auto numRead = (int) ::read(pipeIn, destBuffer, (size_t)maxBytesToRead);
		if (numRead > 0)
			return numRead;

		if (errno != EWOULDBLOCK || stopReadOperation.load() || hasExpired(timeoutEnd))
			return -1;

		const int maxWaitingTime = 30;
		waitForInput(pipeIn, timeoutEnd == 0 ? maxWaitingTime 
					 : jmin(maxWaitingTime, (int)(timeoutEnd - Time::getMillisecondCounter())));

	}
	return -1;}