How to force fgets read from file instead of buffer cache?

Discussion in 'C Programming' started by luke.yolanda@gmail.com, Feb 16, 2010.

  1. Guest

    Hello everybody,

    Actually, I'm trying to read (no write operation) from proc filesystem
    periodically. It turns out that after first read, all subsequent read
    are go to buffercache, not the proc fs (therefore, get the same value
    every time). This problem can be avoided by closing and open it again
    after each read, but I'm wondering if there's a better solution?

    Thank you very much!

    Gen
    , Feb 16, 2010
    #1
    1. Advertising

  2. gwowen Guest

    On Feb 16, 9:33 am, "" <>
    wrote:

    > Actually, I'm trying to read (no write operation) from proc filesystem
    > periodically. It turns out that after first read, all subsequent read
    > are go to buffercache, not the proc fs


    If you are using Linux, I rather suspect this is not the problem. You
    don't provide enought information to be any more helpful than that,
    I'm afraid.
    gwowen, Feb 16, 2010
    #2
    1. Advertising

  3. Seebs Guest

    On 2010-02-16, <> wrote:
    > Hello everybody,
    >
    > Actually, I'm trying to read (no write operation) from proc filesystem
    > periodically. It turns out that after first read, all subsequent read
    > are go to buffercache, not the proc fs (therefore, get the same value
    > every time). This problem can be avoided by closing and open it again
    > after each read, but I'm wondering if there's a better solution?


    "Buffer cache" is 99% likely to be the wrong term here, but details would
    be system-specific.

    Suggestion: Use setvbuf(). If that doesn't work, you'll need to bypass
    stdio.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    Seebs, Feb 16, 2010
    #3
  4. Guest

    On Feb 16, 3:03 am, gwowen <> wrote:
    > On Feb 16, 9:33 am, "" <>
    > wrote:
    >
    > > Actually, I'm trying to read (no write operation) from proc filesystem
    > > periodically. It turns out that after first read, all subsequent read
    > > are go to buffercache, not the proc fs

    >
    > If you are using Linux, I rather suspect this is not the problem.  You
    > don't provide enought information to be any more helpful than that,
    > I'm afraid.


    first of all, thanks for your help.
    yes, it's in linux. I just wrote a simplified version of my code, as
    below:

    /*************************** code start
    ***********************************/
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>


    #define PROC_PATH "/proc/self/net/dev"
    //for you to make this work, change following macro to the name of the
    device you used
    #define DEV_NAME "wlan0"

    #define PERIOD 2

    int main(){
    /*initialization*/
    int bt;
    int i, ret;
    int stat[16];
    char *linebuffer = (char *)malloc(256);
    char *token = (char *)malloc(32);
    if(!linebuffer || !token)
    exit(-1);
    FILE *fp_in;
    fp_in = fopen(PROC_PATH, "r");
    if(!fp_in)
    exit(-2);
    /*read specified entry*/
    for(i=0;i<100;i++){
    bt=0;
    memset(linebuffer, 0, 256);
    memset(token, 0, 32);

    if(fgets(linebuffer, 256, fp_in)==NULL)
    exit(-3);
    ret = sscanf(linebuffer,
    "%[ a-z0-9]: %d %d %d %d %d %d %d %d %d %d %d
    %d %d %d %d %d \n",
    token,

    &stat[0],&stat[1],&stat[2],&stat[3],&stat[4],&stat[5],&stat[6],&stat[7],

    &stat[8],&stat[9],&stat[10],&stat[11],&stat[12],&stat[13],&stat[14],&stat[15]);
    while(*token==' '){
    token++;
    bt++;
    }
    printf("i %d token %s\n",i,token);
    if(strcmp(token, DEV_NAME))
    token -= bt;
    else{
    token -= bt;
    printf("dev:%s\t recv:%d\t trans:%d\n",token, stat[0], stat[8]);

    /*choice #1, close and reopen the file*/
    fclose(fp_in);
    fp_in = fopen(PROC_PATH, "r");
    if(!fp_in)
    exit(-2);
    /*choice #2, rewind the pointer in the stream
    back to the start*/
    //rewind(fp_in);

    sleep(PERIOD);

    }
    }
    fclose(fp_in);
    free(linebuffer);
    free(token);
    }

    /*************************** code end
    ***********************************/

    Please notice the choice #1 and #2 in my comment, when using #1,
    everything's just fine, but after switch to #2 (using rewind(), hope I
    didn't misunderstand its usage, since I've never used it before), it
    will always get the same value over and over. It seems to me that the
    fgets() never go to actual file system again after the first read, and
    goes to buffer cache instead.

    I will try to add some logging in kernel to see what's really going on
    when I get time...

    Thank you guys!

    Gen
    , Feb 17, 2010
    #4
  5. Guest

    On Feb 16, 10:10 am, Seebs <> wrote:
    > On 2010-02-16, <> wrote:
    >
    > > Hello everybody,

    >
    > > Actually, I'm trying to read (no write operation) from proc filesystem
    > > periodically. It turns out that after first read, all subsequent read
    > > are go to buffercache, not the proc fs (therefore, get the same value
    > > every time).  This problem can be avoided by closing and open it again
    > > after each read, but I'm wondering if there's a better solution?

    >
    > "Buffer cache" is 99% likely to be the wrong term here, but details would
    > be system-specific.
    >
    > Suggestion:  Use setvbuf().  If that doesn't work, you'll need to bypass
    > stdio.


    Hi,

    setvbuf seems to be the solution, it works well for me now :)
    Thanks!

    Gen

    >
    > -s
    > --
    > Copyright 2010, all wrongs reversed.  Peter Seebach / ://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    , Feb 17, 2010
    #5
  6. On Feb 17, 12:16 pm, "" <>
    wrote:
    > On Feb 16, 10:10 am, Seebs <> wrote:
    > > Luke wrote:
    > > > Actually, I'm trying to read (no write operation) from proc filesystem

    > > Suggestion:  Use setvbuf().  If that doesn't work, you'll need to bypass
    > > stdio.

    > setvbuf seems to be the solution, it works well for me now :)
    > Thanks!


    It's good that you solved your problem. But ...
    You *know* you're on Unix with code very much OS-dependent;
    *why* would you ever choose fread() over read() in the first place?
    The False Gods of Portability have led you astray.

    (Historical note: I recall espousing read() over fread() for a similar
    purpose about 2 decades ago in this ng, and was condemned by
    Dan Pop who seemed to think that read() could only read 1 character
    at a time!!)

    James
    James Dow Allen, Feb 17, 2010
    #6
  7. On Feb 17, 1:34 pm, James Dow Allen <> wrote:
    > ... Dan Pop who seemed to think that read() could only read 1 character
    > at a time!!)


    I clicked Send too hurriedly, misquoting Mr. Pop, whose point
    seemed to be that a programmer smart enough to bypass fread()
    for read() for certain OS-specific tasks, would then stupidly
    use read(0, ..., 1) in preference to getc().

    James
    James Dow Allen, Feb 17, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Justme
    Replies:
    9
    Views:
    600
    clayne
    Oct 1, 2006
  2. Replies:
    16
    Views:
    2,325
    Keith Thompson
    Nov 28, 2006
  3. Neal Becker

    buffer creates only read-only buffer?

    Neal Becker, Jan 8, 2009, in forum: Python
    Replies:
    0
    Views:
    400
    Neal Becker
    Jan 8, 2009
  4. Andy
    Replies:
    3
    Views:
    3,348
  5. John Reye
    Replies:
    43
    Views:
    1,300
    Malcolm McLean
    Nov 14, 2013
Loading...

Share This Page