This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: EOF and ferror
- From: Jonathan Larmour <jlarmour at redhat dot com>
- To: Jurica Baricevic <jura at INTESIS dot hr>
- Cc: Ecos <ecos-discuss at sources dot redhat dot com>
- Date: Thu, 04 Apr 2002 05:21:24 +0100
- Subject: Re: [ECOS] EOF and ferror
- References: <NFBBJGOLDDDGJPLCMJKNEEFMCEAA.jura@intesis.hr>
Jurica Baricevic wrote:
>
> For example, a simple code like this should read bytes from the stream and
> after all bytes are read (or error occurred) it should check for eventual
> error condition with ferror().
> On Windows, if there are no errors reading the file (end of file reached
> normally), ferror() will return false. Unfortunately, on eCos ferror() will
> always return true after getc() reaches EOF.
>
> FILE *infile;
> int c;
>
> if ((infile = fopen("abc.log","r")) == NULL)
> {
> printf("fopen failed.");
> ...
> }
>
> while ((c = getc(infile)) != EOF)
> {
> //Do something with 'c'
> ...
> }
>
> if ferror(infile)
> {
> printf("Error: %d", errno);
> }
>
> ...
>
> In file stream.cxx, line 300 (method Cyg_StdioStream::refill_read_buffer)
> there is:
>
> if (read_err == ENOERR) {
> if (len == 0) {
> read_err = EAGAIN;
> flags.at_eof = true;
> }
> else
> flags.at_eof = false;
> } // if
>
> If I get it right, the (len == 0) indicates end of file and sets
> corresponding flag (flags.at_eof) for eventual call to feof(), which is
> fine.
>
> However, setting 'read_err' to EAGAIN will cause the caller function of
> refill_read_buffer() (for example: fgetc() ) to set the error in current
> stream (Cyg_StdioStream::set_error() ). Therefore, future calls to ferror()
> will indicate an error, although the EOF is no error condition (IMHO).
Good catch. All that's needed is:
Index: src/input/fgetc.cxx
===================================================================
RCS file:
/home/cvs/ecc/ecc/language/c/libc/stdio/current/src/input/fgetc.cxx,v
retrieving revision 1.2
diff -u -5 -p -r1.2 fgetc.cxx
--- src/input/fgetc.cxx 2000/07/25 14:54:47 1.2
+++ src/input/fgetc.cxx 2002/04/04 04:16:35
@@ -83,14 +83,15 @@ fgetc( FILE *stream )
CYG_ASSERT( (ENOERR != err) || (1 == bytes_read), "Didn't read 1
byte!" );
if (err)
{
- real_stream->set_error( err );
- errno = err;
- CYG_REPORT_RETVAL(EOF);
- return EOF;
+ c = EOF;
+ if ( EAGAIN != err ) {
+ real_stream->set_error( err );
+ errno = err;
+ }
} // if
CYG_REPORT_RETVAL((int)c);
return (int)c;
Jifl
--
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss