diff options
Diffstat (limited to 'libio')
-rw-r--r-- | libio/fileops.c | 16 | ||||
-rw-r--r-- | libio/ioseekoff.c | 14 | ||||
-rw-r--r-- | libio/oldfileops.c | 16 | ||||
-rw-r--r-- | libio/rewind.c | 1 |
4 files changed, 40 insertions, 7 deletions
diff --git a/libio/fileops.c b/libio/fileops.c index be65d42fb2..8930f6f3cd 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -567,7 +567,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode) _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); { _IO_mask_flags (fp, 0, _IO_EOF_SEEN); - return offset; + goto resync; } } #ifdef TODO @@ -579,7 +579,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode) if (ignore (to_skip) != to_skip) goto dumb; _IO_mask_flags (fp, 0, _IO_EOF_SEEN); - return offset; + goto resync; } #endif } @@ -590,7 +590,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode) _IO_switch_to_backup_area (fp); gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); _IO_mask_flags (fp, 0, _IO_EOF_SEEN); - return offset; + goto resync; } #endif } @@ -646,6 +646,16 @@ _IO_new_file_seekoff (fp, offset, dir, mode) _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); } return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + the file and the kernel file offset will be changed. */ + if (fp->_offset >= 0) + _IO_SYSSEEK (fp, fp->_offset, 0); + + return offset; } _IO_ssize_t diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c index 54a8d19f0d..4a951dd7c1 100644 --- a/libio/ioseekoff.c +++ b/libio/ioseekoff.c @@ -24,6 +24,13 @@ General Public License. */ #include <libioP.h> +#include <errno.h> +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif _IO_fpos64_t _IO_seekoff (fp, offset, dir, mode) @@ -34,13 +41,18 @@ _IO_seekoff (fp, offset, dir, mode) { _IO_fpos64_t retval; + if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end) + { + __set_errno (EINVAL); + return EOF; + } + /* If we have a backup buffer, get rid of it, since the __seekoff callback may not know to do the right thing about it. This may be over-kill, but it'll do for now. TODO */ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); - if (mode != 0 && _IO_have_backup (fp)) { if (dir == _IO_seek_cur && _IO_in_backup (fp)) diff --git a/libio/oldfileops.c b/libio/oldfileops.c index 59de8d8818..e0f8e65255 100644 --- a/libio/oldfileops.c +++ b/libio/oldfileops.c @@ -514,7 +514,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode) _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset, fp->_IO_read_end); _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); - return offset; + goto resync; } #ifdef TODO /* If we have streammarkers, seek forward by reading ahead. */ @@ -524,7 +524,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode) - (fp->_IO_read_ptr - fp->_IO_read_base); if (ignore (to_skip) != to_skip) goto dumb; - return offset; + goto resync; } #endif } @@ -534,7 +534,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode) if (!_IO_in_backup (fp)) _IO_switch_to_backup_area (fp); gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); - return offset; + goto resync; } #endif } @@ -590,6 +590,16 @@ _IO_old_file_seekoff (fp, offset, dir, mode) _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); } return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + the file and the kernel file offset will be changed. */ + if (fp->_old_offset >= 0) + _IO_SYSSEEK (fp, fp->_old_offset, 0); + + return offset; } _IO_ssize_t diff --git a/libio/rewind.c b/libio/rewind.c index fb6afbc77a..a9ea36edb6 100644 --- a/libio/rewind.c +++ b/libio/rewind.c @@ -34,6 +34,7 @@ rewind (fp) _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); _IO_flockfile (fp); _IO_rewind (fp); + _IO_clearerr (fp); _IO_funlockfile (fp); _IO_cleanup_region_end (0); } |