diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/crt32/stdio/fseek.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/crt32/stdio/fseek.c')
-rw-r--r-- | private/crt32/stdio/fseek.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/private/crt32/stdio/fseek.c b/private/crt32/stdio/fseek.c new file mode 100644 index 000000000..79a975870 --- /dev/null +++ b/private/crt32/stdio/fseek.c @@ -0,0 +1,258 @@ +/*** +*fseek.c - reposition file pointer on a stream +* +* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines fseek() - move the file pointer to new place in file +* +*Revision History: +* 10-13-83 RN initial version +* 06-26-85 TC added code to allow variable buffer lengths +* 02-10-87 BCM fixed '%' mistakenly used for '/' +* 03-04-87 JCR added errno settings +* 04-16-87 JCR added _IOUNGETC support for bug fix and changes whence +* from unsigned int to int (ANSI conformance) +* 04-17-87 JCR fseek() now clears end-of-file indicator flag _IOEOF +* (for ANSI conformance) +* 04-21-87 JCR be smart about lseek'ing to the end of the file and +* back +* 09-17-87 SKS handle case of '\n' at beginning of buffer (FCRLF flag) +* 09-24-87 JCR fixed an incorrect access to flag _IOEOF +* 09-28-87 JCR Corrected _iob2 indexing (now uses _iob_index() macro). +* 09-30-87 JCR Fixed buffer allocation bug, now use _getbuf() +* 11-04-87 JCR Multi-thread support +* 12-11-87 JCR Added "_LOAD_DS" to declaration +* 01-13-88 JCR Removed unnecessary calls to mthread fileno/feof/ferror +* 03-04-88 JCR Return value from read() must be treated as unsigned +* value +* 05-27-88 PHG Merged DLL and normal versions +* 06-06-88 JCR Optimized _iob2[] references +* 06-15-88 JCR Near reference to _iob[] entries; improve REG variables +* 08-25-88 GJF Don't use FP_OFF() macro for the 386 +* 12-02-88 JCR Added _IOCTRLZ support (fixes bug pertaining to ^Z at +* eof) +* 04-12-89 JCR Ripped out all of the special read-only code. See the +* comments in the routine header for more information. +* 08-17-89 GJF Clean up, now specific to OS/2 2.0 (i.e., 386 flat +* model). Also fixed copyright and indents. +* 02-15-90 GJF Fixed copyright +* 03-19-90 GJF Made calling type _CALLTYPE1, added #include +* <cruntime.h> and removed #include <register.h>. +* 05-29-90 SBM Use _flush, not [_]fflush[_lk] +* 07-23-90 SBM Replaced <assertm.h> by <assert.h> +* 10-02-90 GJF New-style function declarators. +* 01-21-91 GJF ANSI naming. +* 03-27-92 DJM POSIX support. +* 08-08-92 GJF Use seek method constants! +* 08-26-92 GJF Include unistd.h for POSIX build. +* +*******************************************************************************/ + +#include <cruntime.h> +#include <stdio.h> +#include <file2.h> +#include <assert.h> +#ifdef _POSIX_ +#include <unistd.h> +#else +#include <msdos.h> +#endif +#include <errno.h> +#include <malloc.h> +#include <io.h> +#include <stddef.h> +#include <internal.h> +#ifndef _POSIX_ +#include <os2dll.h> +#endif + +/*** +*int fseek(stream, offset, whence) - reposition file pointer +* +*Purpose: +* +* Reposition file pointer to the desired location. The new location +* is calculated as follows: +* { whence=0, beginning of file } +* <offset> bytes + { whence=1, current position } +* { whence=2, end of file } +* +* Be careful to coordinate with buffering. +* +* - - - - - - - - - - - - - +* +* [NOTE: We used to bend over backwards to try and preserve the current +* buffer and maintain disk block alignment. This ended up making our +* code big and slow and complicated, and slowed us down quite a bit. +* Some of the things pertinent to the old implimentation: +* +* (1) Read-only: We only did the special code path if the file was +* opened read-only (_IOREAD). If the file was writable, we didn't +* try to optimize. +* +* (2) Buffering: We'd assign a buffer, if necessary, since the +* later code might need it (i.e., call _getbuf). +* +* (3) Ungetc: Fseek had to be careful NOT to save the buffer if +* an ungetc had ever been done on the buffer (flag _IOUNGETC). +* +* (4) Control ^Z: Fseek had to deal with ^Z after reading a +* new buffer's worth of data (flag _IOCTRLZ). +* +* (5) Seek-to-end-and-back: To determine if the new seek was within +* the current buffer, we had to 'normalize' the desired location. +* This means that we sometimes had to seek to the end of the file +* and back to determine what the 0-relative offset was. Two extra +* lseek() calls hurt performance. +* +* (6) CR/LF accounting - When trying to seek within a buffer that +* is in text mode, we had to go account for CR/LF expansion. This +* required us to look at every character up to the new offset and +* see if it was '\n' or not. In addition, we had to check the +* FCRLF flag to see if the new buffer started with '\n'. +* +* Again, all of these notes are for the OLD implimentation just to +* remind folks of some of the issues involving seeking within a buffer +* and maintaining buffer alignment. As an aside, I think this may have +* been a big win in the 'old days' on floppy-based systems but on newer +* fast hard disks, the extra code/complexity overwhelmed any gain. +* +* - - - - - - - - - - - - - +* +*Entry: +* FILE *stream - file to reposition file pointer on +* long offset - offset to seek to +* int whence - origin offset is measured from (0=beg, 1=current pos, +* 2=end) +* +*Exit: +* returns 0 if succeeds +* returns -1 and sets errno if fails +* fields of FILE struct will be changed +* +*Exceptions: +* +*******************************************************************************/ + +#ifdef MTHREAD /* multi-thread; define both fseek() and _lk_fseek() */ + +int _CALLTYPE1 fseek ( + FILE *stream, + long offset, + int whence + ) +{ + int retval; +#ifdef MTHREAD + int index; +#endif + + assert(stream != NULL); + +#ifdef MTHREAD + index = _iob_index(stream); +#endif + + _lock_str(index); + + retval = _fseek_lk (stream, offset, whence); + + _unlock_str(index); + + return(retval); +} + + +/*** +*_fseek_lk() - Core fseek() routine (stream is locked) +* +*Purpose: +* Core fseek() routine; assumes that caller has the stream locked. +* +* [See fseek() for more info.] +* +*Entry: [See fseek()] +* +*Exit: [See fseek()] +* +*Exceptions: +* +*******************************************************************************/ + +int _CALLTYPE1 _fseek_lk ( + +#else /* non multi-thread; just define fseek() */ + +int _CALLTYPE1 fseek ( + +#endif /* rejoin common code */ + + FILE *str, + long offset, + int whence + ) +{ + + + REG1 FILE *stream; + + assert(str != NULL); + + /* Init stream pointer */ + stream = str; + + if ( !inuse(stream) || ((whence != SEEK_SET) && (whence != SEEK_CUR) && + (whence != SEEK_END)) ) { + errno=EINVAL; + return(-1); + } + + /* Clear EOF flag */ + + stream->_flag &= ~_IOEOF; + + /* If seeking relative to current location, then convert to + a seek relative to beginning of file. This accounts for + buffering, etc. by letting fseek() tell us where we are. */ + + if (whence == SEEK_CUR) { + offset += _ftell_lk(stream); + whence = SEEK_SET; + } + + /* Flush buffer as necessary */ + +#ifdef _POSIX_ + /* + * If the stream was last read, we throw away the buffer so + * that a possible subsequent write will encounter a clean + * buffer. (The Win32 version of fflush() throws away the + * buffer if it's read.) Write buffers must be flushed. + */ + + if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOREAD) { + stream->_ptr = stream->_base; + stream->_cnt = 0; + } else { + _flush(stream); + } +#else + _flush(stream); +#endif + + + /* If file opened for read/write, clear flags since we don't know + what the user is going to do next. */ + + if (stream->_flag & _IORW) + stream->_flag &= ~(_IOWRT|_IOREAD); + + /* Seek to the desired locale and return. */ + +#ifdef _POSIX_ + return(lseek(fileno(stream), offset, whence) == -1L ? -1 : 0); +#else + return(_lseek(_fileno(stream), offset, whence) == -1L ? -1 : 0); +#endif +} |