I have the following code that used to work on Ubuntu 18.04. Now, I compiled and run it in Ubuntu 20.04, and, for some reason, the code stop working.
The code is meant to read from a named pipe. To test it, I create the pipe with mkfifo /tmp/pipe
and then I write into the pipe with echo "message" >> /tmp/pipe
.
The first time the fgets()
method is executed, the function returns the expected value from the pipe; but from the second invocation on, the method returns NULL
and the code gets stuck on the loop even when I execute several echo commands.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <sstream>
#include <fstream>
#include <limits>
#include <iomanip>
#include <iostream>
#include <cstdlib>
using namespace std;
FILE* result_pipe_stream;
string read_result_from_pipe(){
if (result_pipe_stream == NULL){
printf("\n[BINDING-COMMONS] ERROR: Pipe is not set");
return NULL;
}
std::stringstream oss;
while (1) {
char buf[BUFSIZ];
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL ) {
int buflen = strlen(buf);
if (buflen >0){
if (buf[buflen-1] == '\n'){
buf[buflen-1] = '\0';
oss << buf;
return oss.str();
} else {
oss << buf;
// line was truncated. Read another block to complete line.
}
}
}
}
}
int main(int argc, char *argv[]){
result_pipe_stream = fopen("/tmp/pipe" , "r");
while (1){
cout << read_result_from_pipe() << '\n';
}
}
- Why is the code not working anymore? I assume that some library has changed in the distribution and fgets is no longer able to read properly from the pipe
- How can I workaround that problem?
CodePudding user response:
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL )
--> Once fgets()
returns NULL
due to end-of-file, it will continue to return NULL
on subsequent calls without reading unless the end-of-file indicator for result_pipe_stream
is cleared - like with clearerr()
. Codes gets stuck in an infinite loop, never reading anymore and it should.
The real question is why it "worked" in Ubuntu 18.04. I suspect that version was not compliant.
while (1) {
char buf[BUFSIZ];
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL ) {
...
}
// Perhaps assess why here, end-of-file, input error, too often here, ...
clearerr(result_pipe_stream); // add
}