summaryrefslogtreecommitdiffstats
path: root/private/crt32/stdio/fseek.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/crt32/stdio/fseek.c
downloadNT4.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.c258
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
+}