Porting from POSIX (FILE*) API to file descriptors. What is theequivalent of...

Discussion in 'C Programming' started by Stephan Beal, Jan 8, 2009.

  1. Stephan Beal

    Stephan Beal Guest

    Hello, all!

    If this question seems off topic, please feel free to ignore it.

    i'm busy porting some code which currently uses the POSIX file API
    (e.g. fopen(), fclose(), fwrite(), etc.) to use the lower-level APIs
    based on file descriptors. The original reason for porting is so that
    i can add locking via fcntl() (and the literature suggests against
    mixing the low-level and (FILE*) APIs), but tests have also shown the
    port to provide a very substantial performance increase for my
    particular use case.

    i've run into a bit of a problem, though...

    i can't seem to find lower-level equivalents for functions like feof
    (), ferror(), and fclearerr(). Do such a things exist for the lower-
    level API (i.e. requiring a file descriptor instead of a (FILE*)? If
    not, is there a way to simulate them? For example, here's my first
    attempt at simulating feof(), but i honestly have no clue if this
    approach is valid using the lower-level API (seems reasonable/naive
    enough, though):

    bool iseof( int fileno )
    {
    off_t p1 = lseek( fileno, 0L, SEEK_CUR );
    off_t p2 = lseek( fileno, 0L, SEEK_END );
    bool rc = (p1 >= p2);
    lseek( fileno, p1, SEEK_SET );
    return rc;
    }

    The routines i'm looking for replacements for (or looking to simulate)
    are:

    - feof()
    - ferror()
    - clearerr()

    all the other operations of the i/o device interface/API i'm working
    inside of can be implemented directly using the lower-level operations
    (e.g. read(), write(), ftruncate(), fdatasync()/fsync(), lseek()).

    Any pointers in the right (or *a* right) direction would be much
    appreciated.

    :)
    Stephan Beal, Jan 8, 2009
    #1
    1. Advertising

  2. Stephan Beal

    Guest

    On Jan 8, 9:06 pm, Stephan Beal <> wrote:

    <snip>

    > The routines i'm looking for replacements for (or looking to simulate)
    > are:
    >
    >   - feof()
    >   - ferror()
    >   - clearerr()


    int feof(FILE *stream) { return stream->eof; }
    int ferror(FILE *stream) { return stream->error; }
    void clearerr(FILE *stream) { stream->error = stream->eof = 0; }
    , Jan 8, 2009
    #2
    1. Advertising

  3. Stephan Beal

    Stephan Beal Guest

    On Jan 8, 8:10 pm, wrote:
    > On Jan 8, 9:06 pm, Stephan Beal <> wrote:
    > > The routines i'm looking for replacements for (or looking to simulate)
    > > are:

    >
    > >   - feof()
    > >   - ferror()
    > >   - clearerr()

    >
    > int feof(FILE *stream) { return stream->eof; }
    > int ferror(FILE *stream) { return stream->error; }
    > void clearerr(FILE *stream) { stream->error = stream->eof = 0; }


    The problem is that i can't mix the FILE and file descriptor APIs
    reliably (at least, literature such as the open() and fopen() man
    pages strongly suggest against it due to buffering in the FILE* API).
    Because i'm doing all i/o with read(), write(), and lseek(), the error
    flags set in a FILE object are not [likely to be] valid (just as the
    FILE handle's cursor position is [probably] not going to match
    reality).

    Internally i'm currently holding both a FILE* and a file descriptor
    (to the same file), and only using the fXXXX() API for those 3
    routines listed above. However, i'm quite certain my use of them is
    bogus because of the problem mentioned in the previous paragraph.
    Stephan Beal, Jan 8, 2009
    #3
  4. Re: Porting from POSIX (FILE*) API to file descriptors. What is the equivalent of...

    writes:
    > On Jan 8, 9:06 pm, Stephan Beal <> wrote:
    > <snip>
    >
    >> The routines i'm looking for replacements for (or looking to simulate)
    >> are:
    >>
    >>   - feof()
    >>   - ferror()
    >>   - clearerr()

    >
    > int feof(FILE *stream) { return stream->eof; }
    > int ferror(FILE *stream) { return stream->error; }
    > void clearerr(FILE *stream) { stream->error = stream->eof = 0; }


    Huh? What makes you think that FILE is a struct type that has members
    named "eof" and "error"?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 8, 2009
    #4
  5. Re: Porting from POSIX (FILE*) API to file descriptors. What is the equivalent of...

    Stephan Beal <> writes:
    > If this question seems off topic, please feel free to ignore it.
    >
    > i'm busy porting some code which currently uses the POSIX file API
    > (e.g. fopen(), fclose(), fwrite(), etc.) to use the lower-level APIs
    > based on file descriptors. The original reason for porting is so that
    > i can add locking via fcntl() (and the literature suggests against
    > mixing the low-level and (FILE*) APIs), but tests have also shown the
    > port to provide a very substantial performance increase for my
    > particular use case.


    I suggest asking about this in comp.unix.programmer (and ignoring the
    trolls who will inevitably jump in to tell you otherwise). The
    lower-level APIs are defined by POSIX, not by the C standard.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 8, 2009
    #5
  6. Stephan Beal

    Guest

    On Jan 8, 10:06 pm, Keith Thompson <> wrote:
    > writes:
    > > On Jan 8, 9:06 pm, Stephan Beal <> wrote:
    > > <snip>

    >
    > >> The routines i'm looking for replacements for (or looking to simulate)
    > >> are:

    >
    > >>   - feof()
    > >>   - ferror()
    > >>   - clearerr()

    >
    > > int feof(FILE *stream) { return stream->eof; }
    > > int ferror(FILE *stream) { return stream->error; }
    > > void clearerr(FILE *stream) { stream->error = stream->eof = 0; }

    >
    > Huh?  What makes you think that FILE is a struct type that has members
    > named "eof" and "error"?


    My point was that he was not really looking for what he thought to be
    looking for, since an arbitrary implementation of those functions is
    of no use.
    , Jan 8, 2009
    #6
  7. Re: Porting from POSIX (FILE*) API to file descriptors. What is the equivalent of...

    writes:
    > On Jan 8, 10:06 pm, Keith Thompson <> wrote:
    >> writes:
    >> > On Jan 8, 9:06 pm, Stephan Beal <> wrote:
    >> > <snip>

    >>
    >> >> The routines i'm looking for replacements for (or looking to simulate)
    >> >> are:

    >>
    >> >>   - feof()
    >> >>   - ferror()
    >> >>   - clearerr()

    >>
    >> > int feof(FILE *stream) { return stream->eof; }
    >> > int ferror(FILE *stream) { return stream->error; }
    >> > void clearerr(FILE *stream) { stream->error = stream->eof = 0; }

    >>
    >> Huh?  What makes you think that FILE is a struct type that has members
    >> named "eof" and "error"?

    >
    > My point was that he was not really looking for what he thought to be
    > looking for, since an arbitrary implementation of those functions is
    > of no use.


    Then make that point.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 8, 2009
    #7
  8. Stephan Beal

    Flash Gordon Guest

    Stephan Beal wrote:
    > Hello, all!
    >
    > If this question seems off topic, please feel free to ignore it.
    >
    > i'm busy porting some code which currently uses the POSIX file API
    > (e.g. fopen(), fclose(), fwrite(), etc.) to use the lower-level APIs


    fopen etc are part of the standard C library which POSIX merely
    inherits, they are not POSIX specific.

    <snip>

    > i can't seem to find lower-level equivalents for functions like feof
    > (), ferror(), and fclearerr(). Do such a things exist for the lower-
    > level API (i.e. requiring a file descriptor instead of a (FILE*)? If
    > not, is there a way to simulate them? For example, here's my first


    <snip>

    By the low-level API I'm guessing you mean open, read etc which actually
    *are* defined by POSIX (although some non-POSIX systems also have
    similarly named functions). So I suggest you read the man pages (or
    equivalent documentation) for them paying attention to return values and
    error handling provided by them and then go over to comp.unix.programmer
    to ask further questions about them.

    Be aware that at least some of the trolls who may provide
    helpful-looking answers are proven liars, so any answers you get here
    (where POSIX is not topical) may be completely or subtly wrong and there
    is no guarantee that a correction would be provided.
    --
    Flash Gordon
    Flash Gordon, Jan 8, 2009
    #8
  9. Stephan Beal wrote:
    > i'm busy porting some code which currently uses the POSIX file API
    > (e.g. fopen(), fclose(), fwrite(), etc.) to use the lower-level APIs
    > based on file descriptors.


    You seem to be confused. FILE* objects are used by the C standard I/O
    library. POSIX defines an API that uses what it calls "file descriptors".

    The folks in comp.unix.programmer should be able to help you with the
    latter; it is off-topic here.

    <OT>

    > i can't seem to find lower-level equivalents for functions like feof
    > (), ferror(), and fclearerr(). Do such a things exist for the lower-
    > level API (i.e. requiring a file descriptor instead of a (FILE*)? If
    > not, is there a way to simulate them?


    There are no direct POSIX equivalents to those functions, nor are they
    needed; EOF and errors are communicated using a different method that
    does not require them. Look in the man pages for the functions you are
    using and pay close attention to the "Return Value" and "Errors" sections.

    </OT>

    S

    --
    Stephen Sprunk "Stupid people surround themselves with smart
    CCIE #3723 people. Smart people surround themselves with
    K5SSS smart people who disagree with them." --Isaac Jaffe
    Stephen Sprunk, Jan 8, 2009
    #9
  10. Stephan Beal

    Stephan Beal Guest

    On Jan 8, 9:51 pm, Flash Gordon <> wrote:
    > By the low-level API I'm guessing you mean open, read etc which actually
    > *are* defined by POSIX (although some non-POSIX systems also have
    > similarly named functions). So I suggest you read the man pages (or
    > equivalent documentation) for them paying attention to return values and
    > error handling provided by them and then go over to comp.unix.programmer
    > to ask further questions about them.


    Yes, i mean open(), read(), etc. (and i admit to being confused by
    which standard defines which functions). i've scoured the man pages
    and all of the "see also" references, but i have found no equivalent
    to feof(), ferror(), and clearerr() which works on file descriptors
    (only FILE) handles. Since i have to avoid using the FILE handle and
    the file descriptor APIs for the same object (because the man pages
    say not to), i've grown very curious as to how those ops are achieved
    when one has only a file descriptor.

    i'll take a look over at comp.unix.programmer - thanks for the tip :).

    (And thanks to the rest of you for your time!!!)
    Stephan Beal, Jan 8, 2009
    #10
  11. In article <>,
    Stephan Beal <> wrote:

    >i can't seem to find lower-level equivalents for functions like feof
    >(), ferror(), and fclearerr(). Do such a things exist for the lower-
    >level API (i.e. requiring a file descriptor instead of a (FILE*)?


    The approaches of the two interfaces are rather different, and you
    can't just drop in replacement function calls. You may find yourself
    replicating the code that a stdio implementation used on a Posix-like
    system.

    When end-of-file is encountered reading from a file descriptor
    (typically with read()), 0 is returned. A stdio implementation
    in this case will return EOF from getc(), and record something in
    the FILE structure so that feof() will return true. If an error
    is encountered, read() will return -1, and stdio will again return
    EOF but this time record something so that ferror() returns true.
    You will have to do the same: note the return value from read() and
    act accordingly.

    Some devices, notably terminals, allowing reading after end-of-file,
    because end-of-file just means the user typed the end-of-file
    indication. With file descriptors, you just call read() again;
    with stdio you have to call clearerr() before it will do that.

    So:

    >The routines i'm looking for replacements for (or looking to simulate)
    >are:
    >
    > - feof()


    Note the return value from read, and see whether it was 0.

    > - ferror()


    Note the return value from read, and see whether it was -1.

    > - clearerr()


    No need to do anything, just read() again.

    -- Richard
    --
    Please remember to mention me / in tapes you leave behind.
    Richard Tobin, Jan 8, 2009
    #11
  12. Stephan Beal

    CBFalconer Guest

    wrote:
    > Stephan Beal <> wrote:
    >
    > <snip>
    >
    >> The routines i'm looking for replacements for (or looking to
    >> simulate) are:
    >>
    >> - feof()
    >> - ferror()
    >> - clearerr()

    >
    > int feof(FILE *stream) { return stream->eof; }
    > int ferror(FILE *stream) { return stream->error; }
    > void clearerr(FILE *stream) { stream->error = stream->eof = 0; }


    Horrors. These are all available as standards, see below. In
    addition, accessing the FILE variable is forbidden. There is no
    reason to assume those fields exist.

    7.19.10.1 The clearerr function

    Synopsis
    [#1]
    #include <stdio.h>
    void clearerr(FILE *stream);

    Description

    [#2] The clearerr function clears the end-of-file and error
    indicators for the stream pointed to by stream.

    Returns

    [#3] The clearerr function returns no value.

    7.19.10.2 The feof function

    Synopsis
    [#1]
    #include <stdio.h>
    int feof(FILE *stream);

    Description

    [#2] The feof function tests the end-of-file indicator for
    the stream pointed to by stream.

    Returns

    [#3] The feof function returns nonzero if and only if the
    end-of-file indicator is set for stream.

    7.19.10.3 The ferror function

    Synopsis
    [#1]
    #include <stdio.h>
    int ferror(FILE *stream);

    Description

    [#2] The ferror function tests the error indicator for the
    stream pointed to by stream.

    Returns

    [#3] The ferror function returns nonzero if and only if the
    error indicator is set for stream.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
    CBFalconer, Jan 8, 2009
    #12
    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. Gordon Beaton

    Re: Running out of file descriptors

    Gordon Beaton, Jul 24, 2003, in forum: Java
    Replies:
    0
    Views:
    388
    Gordon Beaton
    Jul 24, 2003
  2. Oz Levanon

    File Descriptors Leak

    Oz Levanon, Nov 25, 2003, in forum: Java
    Replies:
    3
    Views:
    564
    Robert Olofsson
    Nov 25, 2003
  3. JG
    Replies:
    5
    Views:
    413
    Lawrence Kirby
    Feb 8, 2005
  4. DJ Dharme
    Replies:
    2
    Views:
    251
    Maxim Yegorushkin
    Oct 20, 2008
  5. Adam Pridgen
    Replies:
    3
    Views:
    666
    Adam Pridgen
    Feb 24, 2011
Loading...

Share This Page