Code Comments
Programming Forum and web based access to our favorite programming groups.
I need to do something like this, but get the read (fgets in this case)
to block until there is a new line of data. Sort of like tail -f.
FILE *instream = fopen(fname, "rt");
if (instream==NULL) {
return 0;
}
fs
(instream, 0L, SEEK_END);
while(1) {
cptr = fgets(buf, sizeof(buf), instream);
if (cptr==NULL) {
printf("exiting because there is no data\n");
break;
}
printf(cptr);
}
fclose(instream);
How can this be done in unix?
Jim
Post Follow-up to this messageJames Johnson wrote :
> I need to do something like this, but get the read (fgets in this case)
> to block until there is a new line of data. Sort of like tail -f.
>
> FILE *instream = fopen(fname, "rt");
> if (instream==NULL) {
> return 0;
> }
> fs
(instream, 0L, SEEK_END);
>
> while(1) {
> cptr = fgets(buf, sizeof(buf), instream);
> if (cptr==NULL) {
> printf("exiting because there is no data\n");
> break;
> }
> printf(cptr);
> }
>
> fclose(instream);
>
>
> How can this be done in unix?
tail will poll for new data when it reaches the end of the file.
On some unix, you can use kqueue or the linux equivalent to avoid
polling.
--
DINH V. Hoa,
"tuning et dope, aucun rapport" -- b.
Post Follow-up to this messageOn Tue, 28 Dec 2004 18:13:47 +0100, DINH Viet Hoa <dinh.viet.hoa@free.fr> wrote: >James Johnson wrote : > > >tail will poll for new data when it reaches the end of the file. > >On some unix, you can use kqueue or the linux equivalent to avoid >polling. tail is a shell command. I want to do this in C. Jim
Post Follow-up to this messageOn 2004-12-28, James Johnson <jj@yaaho.com> wrote:
>
>
> I need to do something like this, but get the read (fgets in this case)
> to block until there is a new line of data. Sort of like tail -f.
>
> FILE *instream = fopen(fname, "rt");
> if (instream==NULL) {
> return 0;
> }
> fs
(instream, 0L, SEEK_END);
>
> while(1) {
> cptr = fgets(buf, sizeof(buf), instream);
> if (cptr==NULL) {
> printf("exiting because there is no data\n");
> break;
> }
> printf(cptr);
> }
>
> fclose(instream);
>
>
> How can this be done in unix?
On linux, normally one calls fgets, if NULL then sleeps for a while, and
after that tries again. Check the strace of tail -f, you'll see it.
I don't believe (though I don't know it ;) that there's any other way.
Andrei
Post Follow-up to this messageJames Johnson wrote:
>
> I need to do something like this, but get the read (fgets in this case)
> to block until there is a new line of data. Sort of like tail -f.
"sort of"? I can't help you with "sort of" but if it needs to do what
tail does you have to periodically use stat/fstat to check the length
of the file and see if it has grown beyond the position you previous
read up to.
-- ced
>
> FILE *instream = fopen(fname, "rt");
> if (instream==NULL) {
> return 0;
> }
> fs
(instream, 0L, SEEK_END);
>
> while(1) {
> cptr = fgets(buf, sizeof(buf), instream);
> if (cptr==NULL) {
> printf("exiting because there is no data\n");
> break;
> }
> printf(cptr);
> }
>
> fclose(instream);
>
>
> How can this be done in unix?
>
> Jim
>
>
--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.
Post Follow-up to this messageOn Tue, 28 Dec 2004 12:11:02 -0600, Chuck Dillon <spam@nimblegen.com> wrote: >James Johnson wrote: > >"sort of"? I can't help you with "sort of" but if it needs to do what >tail does you have to periodically use stat/fstat to check the length >of the file and see if it has grown beyond the position you previous >read up to. > >-- ced > That's what I'm currently doing: if the filesize changes read until an eof, then sleep. That "sort of" works the same as tail -f. I wasn't sure if that's how it should be done. I heard that there was a way to read a file that blocks until new data is available. That seems to be a better way, since you don't have to poll the file size. If I knew how to do it by a blocking read, I'd rather do it that way. Jim
Post Follow-up to this messageJames Johnson wrote: > > > That's what I'm currently doing: if the filesize changes read until an > eof, then sleep. That "sort of" works the same as tail -f. I wasn't sure > if that's how it should be done. I heard that there was a way to read a > file that blocks until new data is available. That seems to be a better > way, since you don't have to poll the file size. If I knew how to do it > by a blocking read, I'd rather do it that way. > > Jim > There's no way to block until data is added to a regular file without the writer providing some stimulus. Either of the stat or read loop approaches should work. On SunOS(5.8) if you truss (system call tracer) tail -f you will see alarms and reads so it is simply looping on reads with a short sleep (i.e. 1 second). If you do the same (with strace) on linux (2.4.7) you see nonosleeps and fstat64 calls so that implementation is monitoring the size. -- ced -- Chuck Dillon Senior Software Engineer NimbleGen Systems Inc.
Post Follow-up to this messageJames Johnson <jj@yaaho.com> wrote:
>I need to do something like this, but get the read (fgets in this case)
>to block until there is a new line of data. Sort of like tail -f.
>
>FILE *instream = fopen(fname, "rt");
>if (instream==NULL) {
> return 0;
>}
>fs
(instream, 0L, SEEK_END);
>
>while(1) {
> cptr = fgets(buf, sizeof(buf), instream);
> if (cptr==NULL) {
> printf("exiting because there is no data\n");
> break;
> }
> printf(cptr);
>}
>
>fclose(instream);
>
>How can this be done in unix?
You can do it with ANSI C, hence there is absolutely no
difference for various platforms. Consider this snippet:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
..
char buf[BUFSIZ];
fpos_t pos;
FILE *fp;
if (NULL == (fp = fopen(fname, "rt"))) {
fprintf(stderr,"Cannot find file: %s\n", fname);
exit(EXIT_FAILURE);
}
if ( 0 != fs
(fp, 0, SEEK_END)) {
fprintf(stderr,"Cannot read file: %s\n", fname);
exit(EXIT_FAILURE);
}
if (-1 == fgetpos(fp, &pos)) {
fprintf(stderr,"Cannot read file: %s\n", fname);
exit(EXIT_FAILURE);
}
for (;;) {
fgets(buf, sizeof(buf), instream);
if (ferror(instream)) {
fprintf(stderr,"Error reading file: %s\n", name);
exit(EXIT_FAILURE);
}
if (feof(instream)) {
fsetpos(instream, &pos);
clearerr(instream);
usleep(10000); /* give up the cpu to other processes */
continue;
}
fgetpos(instream, &pos);
printf("%s", buf);
fflush(stdout);
}
--
Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) floyd@barrow.com
Post Follow-up to this message"James Johnson" <jj@yaaho.com> wrote in message news:26a3t0togm9269t4rnh3sqt608qftlrcse@ 4ax.com... > That's what I'm currently doing: if the filesize changes read until an > eof, then sleep. That "sort of" works the same as tail -f. I wasn't sure > if that's how it should be done. I heard that there was a way to read a > file that blocks until new data is available. That seems to be a better > way, since you don't have to poll the file size. If I knew how to do it > by a blocking read, I'd rather do it that way. There is no direct way to block until new data is available. The file is always readable, and so will never block. You might want to google (or check your manual pages) for information on FAM (file alteration monitor). On Linux, you can use 'gamin'. http://oss.sgi.com/projects/fam/ http://www.gnome.org/~veillard/gamin/overview.html Many UNIXes have platform-specific ways to do this too. DS
Post Follow-up to this messageOn 29 Dec 2004 14:38:55 +0100 Maurizio Loreti <mlo@foobar.it> wrote: > Are you asserting that this is required by POSIX? Are you asserting > that a 'tail' implementation *must* be written in C --- and not C++, > FORTRAN or awk or any other language? Your ability to read between the lines rivals the soothsayer's art of glimpsing the future from rabbit entrails - and is equally accurate. -- Stefaan -- As complexity rises, precise statements lose meaning, and meaningful statements lose precision. -- Lotfi Zadeh
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.