windows-nt/Source/XPSP1/NT/base/crts/crtw32/lowio/lseeki64.c

191 lines
5.2 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/***
*lseeki64.c - change file position
*
* Copyright (c) 1994-2001, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines _lseeki64() - move the file pointer
*
*Revision History:
* 11-16-94 GJF Created. Adapted from lseek.c
* 03-13-95 CFW Verify handles before passing to OS.
* 06-12-95 GJF Replaced _osfile[] with _osfile() (macro referencing
* field in ioinfo struct).
* 06-26-95 GJF Added check that the file handle is open.
* 12-19-97 GJF Exception-safe locking.
*
*******************************************************************************/
#include <cruntime.h>
#include <oscalls.h>
#include <mtdll.h>
#include <io.h>
#include <internal.h>
#include <stdlib.h>
#include <errno.h>
#include <msdos.h>
#include <stdio.h>
/*
* Convenient union for accessing the upper and lower 32-bits of a 64-bit
* integer.
*/
typedef union doubleint {
__int64 bigint;
struct {
unsigned long lowerhalf;
long upperhalf;
} twoints;
} DINT;
/***
*__int64 _lseeki64( fh, pos, mthd ) - move the file pointer
*
*Purpose:
* Moves the file pointer associated with fh to a new position. The new
* position is pos bytes (pos may be negative) away from the origin
* specified by mthd.
*
* If mthd == SEEK_SET, the origin in the beginning of file
* If mthd == SEEK_CUR, the origin is the current file pointer position
* If mthd == SEEK_END, the origin is the end of the file
*
* Multi-thread:
* _lseeki64() = locks/unlocks the file
* _lseeki64_lk() = does NOT lock/unlock the file (it is assumed that
* the caller has the aquired the file lock, if needed).
*
*Entry:
* int fh - file handle to move file pointer on
* __int64 pos - position to move to, relative to origin
* int mthd - specifies the origin pos is relative to (see above)
*
*Exit:
* returns the offset, in bytes, of the new position from the beginning
* of the file.
* returns -1i64 (and sets errno) if fails.
* Note that seeking beyond the end of the file is not an error.
* (although seeking before the beginning is.)
*
*Exceptions:
*
*******************************************************************************/
#ifdef _MT
__int64 __cdecl _lseeki64 (
int fh,
__int64 pos,
int mthd
)
{
__int64 r;
/* validate fh */
if ( ((unsigned)fh >= (unsigned)_nhandle) ||
!(_osfile(fh) & FOPEN) )
{
/* bad file handle */
errno = EBADF;
_doserrno = 0; /* not OS error */
return( -1i64 );
}
_lock_fh(fh); /* lock file handle */
__try {
if ( _osfile(fh) & FOPEN )
r = _lseeki64_lk( fh, pos, mthd ); /* seek */
else {
errno = EBADF;
_doserrno = 0; /* not OS error */
r = -1i64;
}
}
__finally {
_unlock_fh(fh); /* unlock file handle */
}
return( r );
}
/***
*__int64 _lseeki64_lk( fh, pos, mthd ) - move the file pointer
*
*Purpose:
* Non-locking version of _lseeki64 for internal use only.
*
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
__int64 __cdecl _lseeki64_lk (
int fh,
__int64 pos,
int mthd
)
{
DINT newpos; /* new file position */
unsigned long errcode; /* error code from API call */
HANDLE osHandle; /* o.s. handle value */
#else /* ndef _MT */
__int64 __cdecl _lseeki64 (
int fh,
__int64 pos,
int mthd
)
{
DINT newpos; /* new file position */
unsigned long errcode; /* error code from API call */
HANDLE osHandle; /* o.s. handle value */
/* validate fh */
if ( ((unsigned)fh >= (unsigned)_nhandle) ||
!(_osfile(fh) & FOPEN) )
{
/* bad file handle */
errno = EBADF;
_doserrno = 0; /* not OS error */
return( -1i64 );
}
#endif /* _MT */
newpos.bigint = pos;
/* tell OS to seek */
#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END /*IFSTRIP=IGN*/
#error Xenix and Win32 seek constants not compatible
#endif
if ((osHandle = (HANDLE)_get_osfhandle(fh)) == (HANDLE)-1)
{
errno = EBADF;
return( -1i64 );
}
if ( ((newpos.twoints.lowerhalf =
SetFilePointer( osHandle,
newpos.twoints.lowerhalf,
&(newpos.twoints.upperhalf),
mthd )) == -1L) &&
((errcode = GetLastError()) != NO_ERROR) )
{
_dosmaperr( errcode );
return( -1i64 );
}
_osfile(fh) &= ~FEOFLAG; /* clear the ctrl-z flag on the file */
return( newpos.bigint ); /* return */
}