Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent fgets blocks when file stream has no new data

Tags:

c

popen

fgets

I have a popen() function which executes tail -f sometextfile. Aslong as there is data in the filestream obviously I can get the data through fgets(). Now, if no new data comes from tail, fgets() hangs. I tried ferror() and feof() to no avail. How can I make sure fgets() doesn't try to read data when nothing new is in the file stream?

One of the suggestion was select(). Since this is for Windows Platform select doesn't seem to work as anonymous pipes do not seem to work for it (see this post).

like image 632
SinisterDex Avatar asked Sep 29 '08 17:09

SinisterDex


People also ask

Does fgets read new line?

The fgets function reads characters from the stream stream up to and including a newline character and stores them in the string s , adding a null character to mark the end of the string.

How does fgets work in C?

fgets() function in CThe function reads a text line or a string from the specified file or console. And then stores it to the respective string variable. Similar to the gets() function, fgets also terminates reading whenever it encounters a newline character.


2 Answers

In Linux (or any Unix-y OS), you can mark the underlying file descriptor used by popen() to be non-blocking.

#include <fcntl.h>

FILE *proc = popen("tail -f /tmp/test.txt", "r");
int fd = fileno(proc);

int flags;
flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);

If there is no input available, fgets will return NULL with errno set to EWOULDBLOCK.

like image 55
DGentry Avatar answered Sep 20 '22 21:09

DGentry


fgets() is a blocking read, it is supposed to wait until data is available if there is no data.

You'll want to perform asynchronous I/O using select(), poll(), or epoll(). And then perform a read from the file descriptor when there is data available.

These functions use the file descriptor of the FILE* handle, retrieved by: int fd = fileno(f);

like image 42
Sufian Avatar answered Sep 20 '22 21:09

Sufian