tags:

views:

2389

answers:

5

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).

A: 

I you would use POSIX functions for IO instead of those of C library, you could use select or poll.

Kasprzol
A: 

You can instead try reading sometextfile using low-level IO functions (open(), read(), etc.), like tail itself does. When there's nothing more to read, read() returns zero, but will still try to read more the next time, unlike FILE* functions.

Lev
this was just an example. the idea is to pull data and pass it through a mutex object to a flash instance.
SinisterDex
+8  A: 

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);

Sufian
Definitely use select() - if you have a FILE * and you need a file descriptor, use fileno(). If you have a file descriptor and you need a FILE *, use fdopen().
plinth
Good suggestion, edited to include fileno.
Sufian
Unfortunately, I think select() doesn't work on pipes under Windows.
Roddy
+6  A: 

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);

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.

DGentry
A: 

i solved my problems by using threads , specifically _beginthread , _beginthreadex.

SinisterDex