This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: EOF and ferror


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]