From bug-request at octave dot org Tue Nov 30 03:26:57 2004 Subject: Re: fseek: return status instead of stopping with an error From: Alois Schloegl To: "John W. Eaton" CC: bug at octave dot org Date: Tue, 30 Nov 2004 10:22:26 +0100 John W. Eaton wrote: >On 21-Oct-2004, I wrote: > >| On 21-Oct-2004, Alois Schloegl wrote: >| >| | Usually, one would expect that "status" in status=fseek(...). can be >| | used to check whether fseek was successful or not. Pointing somewhere >| | outside of the range [0:filesize] should return status=-1 and the >| | pointer should not have changed. >| >| Again, I don't see an easy way to do this, since at least on my >| system, the underlying C library fseek function does not return -1 if >| you seek outside the bounds of the file. Does anyone have suggestions >| for a good method to achieve this behavior in a portable way? > >I think the following patch will make Octave behave the way you want >even if fseek doesn't return failure for seeking beyond the end of the >file. It will slow fseek down a bit, but I don't see a better >solution. Does anyone else see a better way to do this? >Thanks, > >jwe > > > How about checking the size of the file during FOPEN? And saving the size somewhere within the file handle. FSEEK should be able to access this size field, and it check whether the file handle points beyond the end-of-file. This would eliminate the need of up to three rep->seek's within fseek. What do you think? Alois >src/ChangeLog: > >2004-11-04 John W. Eaton > > * oct-stream.cc (octave_stream::seek (long, int)): Return error > (but leave file position unchanged) for attempt to seek beyond end > of file. > > >Index: src/oct-stream.cc >=================================================================== >RCS file: /usr/local/cvsroot/octave/src/oct-stream.cc,v >retrieving revision 1.109 >diff -u -r1.109 oct-stream.cc >--- src/oct-stream.cc 24 Sep 2004 03:22:24 -0000 1.109 >+++ src/oct-stream.cc 4 Nov 2004 19:27:22 -0000 > at @ -2663,16 +2663,40 @@ > int > octave_stream::seek (long offset, int origin) > { >- int retval = -1; >+ int status = -1; > > if (stream_ok ("fseek")) > { > clearerr (); > >- retval = rep->seek (offset, origin); >+ long orig_pos = rep->tell (); >+ >+ status = rep->seek (offset, origin); >+ >+ if (status == 0) >+ { >+ long save_pos = rep->tell (); >+ >+ rep->seek (0, SEEK_END); >+ >+ long pos_eof = rep->tell (); >+ >+ if (save_pos > pos_eof) >+ { >+ // Failure should leave position unchanged. >+ >+ rep->seek (orig_pos, SEEK_SET); >+ >+ status = -1; >+ >+ error ("fseek: invalid seek to position beyond end of file"); >+ } >+ else >+ rep->seek (save_pos, SEEK_SET); >+ } > } > >- return retval; >+ return status; > } > > int > > ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------