# HG changeset patch # User John W. Eaton # Date 1312987961 14400 # Node ID 8372d50de75a823392af7ce7fcf67d95faf8299e # Parent 1be5f06d9fa77a4e6d8ab122612db915d060f27c improve logic of octave_stream::seek funtion * oct-stream.cc (octave_stream::seek): Find initial and EOF positions before attempting to seek to requested position. diff -r 1be5f06d9fa7 -r 8372d50de75a src/oct-stream.cc --- a/src/oct-stream.cc Tue Aug 09 23:23:59 2011 -0400 +++ b/src/oct-stream.cc Wed Aug 10 10:52:41 2011 -0400 @@ -2860,38 +2860,60 @@ { clearerr (); + // Find current position so we can return to it if needed. + long orig_pos = rep->tell (); - status = rep->seek (offset, origin); + // Move to end of file. If successful, find the offset of the end. + + status = rep->seek (0, SEEK_END); if (status == 0) { - long save_pos = rep->tell (); - - rep->seek (0, SEEK_END); - - long pos_eof = rep->tell (); - - // I don't think save_pos can be less than zero, but we'll - // check anyway... - - if (save_pos > pos_eof || save_pos < 0) + long eof_pos = rep->tell (); + + if (origin == SEEK_CUR) + { + // Move back to original position, otherwise we will be + // seeking from the end of file which is probably not the + // original location. + + rep->seek (orig_pos, SEEK_SET); + } + + // Attempt to move to desired position; may be outside bounds + // of existing file. + + status = rep->seek (offset, origin); + + if (status == 0) { - // Seek outside bounds of file. Failure should leave - // position unchanged. + // Where are we after moving to desired position? + + long desired_pos = rep->tell (); + + // I don't think save_pos can be less than zero, but we'll + // check anyway... + + if (desired_pos > eof_pos || desired_pos < 0) + { + // Seek outside bounds of file. Failure should leave + // position unchanged. + + rep->seek (orig_pos, SEEK_SET); + + status = -1; + } + } + else + { + // Seeking to the desired position failed. Move back to + // original position and return failure status. rep->seek (orig_pos, SEEK_SET); status = -1; } - else - { - // Is it possible for this to fail? We are just - // returning to a position after the first successful - // seek. - - rep->seek (save_pos, SEEK_SET); - } } }