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

S

Stephan Beal

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.

:)
 
V

vippstar

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; }
 
S

Stephan Beal

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

Keith Thompson

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"?
 
K

Keith Thompson

Stephan Beal said:
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.
 
V

vippstar

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

Keith Thompson

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

Flash Gordon

Stephan said:
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.

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

Stephen Sprunk

Stephan said:
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.

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
 
S

Stephan Beal

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!!!)
 
R

Richard Tobin

Stephan Beal said:
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
 
C

CBFalconer

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top