[ECOS] JFFS2 fseek

Andrew Lunn andrew@lunn.ch
Sat Mar 27 21:14:00 GMT 2004


On Thu, Mar 25, 2004 at 02:25:25PM +0000, eibach@gdsys.de wrote:
> Hello,
> 
> I have a problem with the following code:
> 
> fp = fopen("/jffs2/sys/testfile","w");
> fseek(fp, 512, SEEK_SET);
> fputs("End\n", fp);
> stat = fseek(fp, 0, SEEK_SET);
> fputs("Begin\n", fp);
> fclose(fp);
> 
> It should produce testfile:
> Begin
> <free space>
> End
> 
> Instead it produces:
> End
> Begin
> <free space>
> 
> I had some debugging and found that fseek is executed immedeatly, but fputs is executed when the file is closed.
> 
> The following code is a workaround:
> 
> fp = fopen("/jffs2/sys/testfile","w");
> fseek(fp, 512, SEEK_SET);
> fputs("End\n", fp);
> fflush(fp);
> stat = fseek(fp, 0, SEEK_SET);
> fputs("Begin\n", fp);
> fflush(fp);
> fclose(fp);
> 
> So something seems to be terribly wrong with fseek. Any suggestions where to start searching?
> 

packages/language/c/libc/stdio/current/include/stream.inl 
method Cyg_StdioStream::set_position( fpos_t pos, int whence )

There looks to be a logic bug...

    Cyg_ErrNo err;
    off_t newpos=pos;
 
    err = cyg_stdio_lseek( my_device, &newpos, whence );
 
    if( err == ENOERR )
    {
        // Clean out the buffer. Flush output if any present,
        // and clear any input out of input buffer and any ungot
        // chars from unread buffer.
                                                                                                             
        err = flush_output_unlocked();
        io_buf.drain_buffer();

It appears to be working out where the new position is and then
seeking the file descriptor to the new position. It then flushed the
stream write buffer and resets the input buffer. 

To me, this seems to be in the wrong order. It should flush the
buffers before moving the file pointer. Attached is a totally untested
patch. It might work. Please give it a try and let me know.

       Andrew
-------------- next part --------------
Index: language/c/libc//stdio/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/language/c/libc/stdio/current/ChangeLog,v
retrieving revision 1.26
diff -u -r1.26 ChangeLog
--- language/c/libc//stdio/current/ChangeLog	15 Mar 2004 16:31:57 -0000	1.26
+++ language/c/libc//stdio/current/ChangeLog	27 Mar 2004 21:13:30 -0000
@@ -1,3 +1,9 @@
+2004-03-27  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* include/stream.inl (set_position): Flush the output buffer
+	before seeking the underlying file otherwise the writes end up in
+	the wrong location in the file.
+	
 2004-03-15  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* src/common/fileops.cxx (tmpnam): Only close if open() succeded.
Index: language/c/libc//stdio/current/include/stream.inl
===================================================================
RCS file: /cvs/ecos/ecos/packages/language/c/libc/stdio/current/include/stream.inl,v
retrieving revision 1.6
diff -u -r1.6 stream.inl
--- language/c/libc//stdio/current/include/stream.inl	2 Sep 2002 07:55:38 -0000	1.6
+++ language/c/libc//stdio/current/include/stream.inl	27 Mar 2004 21:13:31 -0000
@@ -446,27 +446,32 @@
     } //endif (whence != SEEK_END)
 
     Cyg_ErrNo err;
-    off_t newpos=pos;
 
-    err = cyg_stdio_lseek( my_device, &newpos, whence );
+    // Flush output if any present.
+    err = flush_output_unlocked();
 
     if( err == ENOERR )
     {
-        // Clean out the buffer. Flush output if any present,
-        // and clear any input out of input buffer and any ungot
-        // chars from unread buffer.
-    
-        err = flush_output_unlocked();
+        off_t newpos=pos;
+ 
+        // Clear any input out of input buffer and any ungot chars
+        // from unread buffer.
         io_buf.drain_buffer();
+    
 #ifdef CYGFUN_LIBC_STDIO_ungetc
         flags.unread_char_buf_in_use = false;
 #endif
 
         // Clear EOF indicator.
         flags.at_eof = false;
-        
-        // update stream pos
-        position = newpos;
+
+        // Seek the file to the correct place
+        err = cyg_stdio_lseek( my_device, &newpos, whence );
+       
+        if ( err == ENOERR) {
+          // update stream pos
+          position = newpos;
+        }
     }
     
     unlock_me();

-------------- next part --------------
-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


More information about the Ecos-discuss mailing list