My C++ code opens a named pipe and calls gzip ... &
at the background, with system()
to get the named pipe as input and output compressed text to a file. However, after that the program hangs when opening the named pipe for writing.
Must the pipe be opened for writing before calling gzip
?
Is it possible to open the named pipe for writing later (after opening it for reading)? The point is that the part for mkfifo
and gzip
call is in a function which I cannot modify, and the same function returns the name of the named pipe.
//...
mkfifo(pipePath, 0644);
std::stringstream strm;
strm << "gzip -c '" << pipePath << "' > '" << outFile << "' &";
system(strm.str().c_str());
ofstream fstrm;
fstrm.open(pipePath, std::ios_base::out);
//...
Other interesting fact is that sometimes the program doesn`t hang but sometimes it does.
6
The issue is that named pipes block until both ends are open. Since gzip
opens the pipe for reading, your program hangs trying to open the pipe for writing after gzip
starts. To fix this, you need to open the pipe for writing before calling gzip
.
Here’s a probable solution:
Pre-open the pipe for writing:
Open the pipe non-blocking for writing before calling gzip.
Close it, then reopen it later when ready to write data.
// Pre-open pipe for writing (non-blocking)
int fd = open(pipePath, O_WRONLY | O_NONBLOCK);
if (fd >= 0) close(fd);
// Call gzip in the background
std::stringstream strm;
strm << "gzip -c '" << pipePath << "' > '" << outFile << "' &";
system(strm.str().c_str());
// Now open the pipe for writing (blocks until ready)
std::ofstream fstrm;
fstrm.open(pipePath, std::ios_base::out);
This ensures the pipe is ready when gzip tries to read from it. Give it a try.
2