This is the mail archive of the ecos-patches@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]

STDIO - proposed fix for fread()


The 'fread()' function works differently on eCos than it does on Linux. 
Thusly, some programs which work fine on Linux fail on eCos.  The 
problem is that fread() sets ferror() when it gets to the end of the 
file (as well as setting feof()).  This patch fixes it, and also adds a 
test for the condition.

Does it make sense?  Shall I commit?

Index: language/c/libc/stdio/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/language/c/libc/stdio/current/ChangeLog,v
retrieving revision 1.20
diff -u -5 -p -b -r1.20 ChangeLog
--- language/c/libc/stdio/current/ChangeLog	24 Feb 2003 14:27:48 -0000	1.20
+++ language/c/libc/stdio/current/ChangeLog	6 Mar 2003 17:36:52 -0000
@@ -1,5 +1,12 @@
+2003-03-06  Gary Thomas  <gary at mlbassoc dot com>
+
+	* src/input/fread.cxx (fread): Simple EOF should not set error.
+
+	* tests/fileio.c: New file.
+	* cdl/stdio.cdl: Add new file I/O tests.
+
 2003-02-24  Jonathan Larmour  <jifl at eCosCentric dot com>
 
 	* cdl/stdio.cdl: Fix doc link.
 
 2003-02-15  Fabrice Gautier  <Fabrice_Gautier at sdesigns dot com>
Index: language/c/libc/stdio/current/cdl/stdio.cdl
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/language/c/libc/stdio/current/cdl/stdio.cdl,v
retrieving revision 1.9
diff -u -5 -p -b -r1.9 stdio.cdl
--- language/c/libc/stdio/current/cdl/stdio.cdl	24 Feb 2003 14:27:48 -0000	1.9
+++ language/c/libc/stdio/current/cdl/stdio.cdl	6 Mar 2003 16:33:18 -0000
@@ -389,11 +389,14 @@ cdl_package CYGPKG_LIBC_STDIO {
 
         cdl_option CYGPKG_LIBC_STDIO_TESTS {
             display "C library stdio function tests"
             flavor  data
             no_define
-            calculated { "tests/sprintf1 tests/sprintf2 tests/sscanf tests/stdiooutput" }
+            calculated { 
+                "tests/sprintf1 tests/sprintf2 tests/sscanf tests/stdiooutput " 
+                . ((CYGPKG_IO_FILEIO && CYGPKG_FS_RAM) ? "tests/fileio " : "")
+            }
             description   "
                 This option specifies the set of tests for the C library
                 stdio functions."
         }
     }
Index: language/c/libc/stdio/current/src/input/fread.cxx
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/language/c/libc/stdio/current/src/input/fread.cxx,v
retrieving revision 1.4
diff -u -5 -p -b -r1.4 fread.cxx
--- language/c/libc/stdio/current/src/input/fread.cxx	23 May 2002 23:07:18 -0000	1.4
+++ language/c/libc/stdio/current/src/input/fread.cxx	6 Mar 2003 17:33:55 -0000
@@ -107,12 +107,14 @@ fread( void *ptr, size_t object_size, si
             ptrc += bytes_read;
         } // if
     } // while
 
     if (err) {
+        if (err != EAGAIN) {
             real_stream->set_error( err );
             errno = err;
+        }
     } // if
     
     // we return the number of _objects_ read. Simple division is
     // sufficient as this returns the quotient rather than rounding
     CYG_REPORT_RETVAL( bytes_read/object_size );
Index: language/c/libc/stdio/current/tests/fileio.c
===================================================================
RCS file: language/c/libc/stdio/current/tests/fileio.c
diff -N language/c/libc/stdio/current/tests/fileio.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ language/c/libc/stdio/current/tests/fileio.c	6 Mar 2003 17:34:59 -0000
@@ -0,0 +1,200 @@
+//=================================================================
+//
+//        fileio.c
+//
+//        Testcase for C library file I/O functions
+//
+//=================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):       Gary Thomas
+// Contributors:    
+// Date:            2003-03-06
+// Description:     Contains testcode for C library file I/O functions
+//
+//
+//####DESCRIPTIONEND####
+
+// CONFIGURATION
+
+#include <pkgconf/libc_stdio.h>   // Configuration header
+
+// INCLUDES
+
+#include <stdio.h>                 // All the stdio functions
+#include <errno.h>                 // errno
+#include <cyg/infra/testcase.h>    // Testcase API
+#include <unistd.h>
+#include <cyg/fileio/fileio.h>
+
+#define NUM_TEST_LINES 100
+#define TEST_DIR "/"
+#define TEST_FILE "test.file"
+
+static char errmsg[256];
+
+// FUNCTIONS
+
+static void
+test( CYG_ADDRWORD data )
+{
+    int err, i, lines, len, total_len, expected_len;
+    FILE *fp;
+    char buf[512], *cp;
+
+    err = mount("", TEST_DIR, "ramfs");
+    if (err < 0) {
+        CYG_TEST_FAIL("Can't mount '/' file system");
+        return;
+    }
+
+    err = chdir(TEST_DIR);
+    if (err < 0) {
+        CYG_TEST_FAIL("Can't chdir('/')");
+        return;
+    }
+
+    fp = fopen("TEST_FILE", "w");
+    if (fp == (FILE *)NULL) {
+        CYG_TEST_FAIL("Can't create test file");
+        return;
+    }
+
+    for (i = 0;  i < NUM_TEST_LINES;  i++) {
+        fprintf(fp, "This is line: %d\n", i+1);
+    }
+
+    fclose(fp);
+
+    fp = fopen("TEST_FILE", "r");
+    if (fp == (FILE *)NULL) {
+        CYG_TEST_FAIL("Can't open test file");
+        return;
+    }
+
+    lines = 0;
+    total_len = 0;
+    while ((cp = fgets(buf, sizeof(buf), fp)) != NULL) {
+        lines++;
+        total_len += strlen(buf);
+    }
+    sprintf(errmsg, "Read %d lines, %d bytes", lines, total_len);
+    CYG_TEST_INFO(errmsg);
+    expected_len = total_len;
+
+    if (lines != NUM_TEST_LINES) {        
+        sprintf(errmsg, "Read %d lines, not %d", lines, NUM_TEST_LINES);
+        CYG_TEST_FAIL(errmsg);
+        return;
+    }
+
+    if (ferror(fp)) {
+        CYG_TEST_FAIL("ferror() set");
+        return;
+    }
+
+    if (!feof(fp)) {
+        CYG_TEST_FAIL("feof() not set");
+        return;
+    }
+
+    fclose(fp);
+
+    fp = fopen("TEST_FILE", "r");
+    if (fp == (FILE *)NULL) {
+        CYG_TEST_FAIL("Can't open test file");
+        return;
+    }
+
+    lines = 0;
+    total_len = 0;
+    while ((len = fread(buf, sizeof(buf), 1, fp)) == 1) {
+        lines++;
+        total_len += sizeof(buf);
+    }
+    sprintf(errmsg, "Read %d chunks, %d bytes, err: %d, eof: %d", lines, total_len, ferror(fp), feof(fp));
+    CYG_TEST_INFO(errmsg);
+
+    if (ferror(fp)) {
+        CYG_TEST_FAIL("ferror() set");
+        return;
+    }
+
+    if (!feof(fp)) {
+        CYG_TEST_FAIL("feof() not set");
+        return;
+    }
+
+    if (expected_len != total_len) {
+        if (total_len > expected_len) {
+            CYG_TEST_FAIL("Too many characters read");
+            return;
+        }
+        // There should still be more characters left to read, but less than sizeof(buf)
+        clearerr(fp);
+        rewind(fp);
+        fseek(fp, total_len, SEEK_SET);
+        len = fread(buf, 1, sizeof(buf), fp);
+        if (len != (expected_len - total_len)) {
+            sprintf(errmsg, "Wrong number of residual bytes - read %d, should be %d", 
+                    len, expected_len-total_len);
+            CYG_TEST_FAIL(errmsg);
+            return;
+        }
+    }
+
+    fclose(fp);
+
+    CYG_TEST_PASS("Stdio file I/O tests completed");
+    CYG_TEST_FINISH("Finished tests from testcase " __FILE__
+                    " for C library stdio file I/O functions");
+} // test()
+
+int
+main(int argc, char *argv[])
+{
+    CYG_TEST_INIT();
+
+    CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C "
+                  "library stdio file I/O functions");
+
+    test(0);
+
+    return 0;
+
+} // main()
+
+// EOF fileio.c


-- 
------------------------------------------------------------
Gary Thomas                 |
MLB Associates              |  Consulting for the
+1 (970) 229-1963           |    Embedded world
http://www.mlbassoc.com/    |
email: <gary at mlbassoc dot com>  |
gpg: http://www.chez-thomas.org/gary/gpg_key.asc
------------------------------------------------------------


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