home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / lseeki64.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  5KB  |  173 lines

  1. /***
  2. *lseeki64.c - change file position
  3. *
  4. *       Copyright (c) 1994-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines _lseeki64() - move the file pointer
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <cruntime.h>
  12. #include <oscalls.h>
  13. #include <mtdll.h>
  14. #include <io.h>
  15. #include <internal.h>
  16. #include <stdlib.h>
  17. #include <errno.h>
  18. #include <msdos.h>
  19. #include <stdio.h>
  20.  
  21. /*
  22.  * Convenient union for accessing the upper and lower 32-bits of a 64-bit
  23.  * integer.
  24.  */
  25. typedef union doubleint {
  26.         __int64 bigint;
  27.         struct {
  28.             unsigned long lowerhalf;
  29.             long upperhalf;
  30.         } twoints;
  31. } DINT;
  32.  
  33.  
  34. /***
  35. *__int64 _lseeki64( fh, pos, mthd ) - move the file pointer
  36. *
  37. *Purpose:
  38. *       Moves the file pointer associated with fh to a new position. The new
  39. *       position is pos bytes (pos may be negative) away from the origin
  40. *       specified by mthd.
  41. *
  42. *       If mthd == SEEK_SET, the origin in the beginning of file
  43. *       If mthd == SEEK_CUR, the origin is the current file pointer position
  44. *       If mthd == SEEK_END, the origin is the end of the file
  45. *
  46. *       Multi-thread:
  47. *       _lseeki64()    = locks/unlocks the file
  48. *       _lseeki64_lk() = does NOT lock/unlock the file (it is assumed that
  49. *                        the caller has the aquired the file lock, if needed).
  50. *
  51. *Entry:
  52. *       int     fh   - file handle to move file pointer on
  53. *       __int64 pos  - position to move to, relative to origin
  54. *       int     mthd - specifies the origin pos is relative to (see above)
  55. *
  56. *Exit:
  57. *       returns the offset, in bytes, of the new position from the beginning
  58. *       of the file.
  59. *       returns -1i64 (and sets errno) if fails.
  60. *       Note that seeking beyond the end of the file is not an error.
  61. *       (although seeking before the beginning is.)
  62. *
  63. *Exceptions:
  64. *
  65. *******************************************************************************/
  66.  
  67. #ifdef _MT
  68.  
  69. __int64 __cdecl _lseeki64 (
  70.         int fh,
  71.         __int64 pos,
  72.         int mthd
  73.         )
  74. {
  75.         __int64 r;
  76.  
  77.         /* validate fh */
  78.  
  79.         if ( ((unsigned)fh >= (unsigned)_nhandle) ||
  80.              !(_osfile(fh) & FOPEN) )
  81.         {
  82.                 /* bad file handle */
  83.                 errno = EBADF;
  84.                 _doserrno = 0;          /* not OS error */
  85.                 return( -1i64 );
  86.         }
  87.  
  88.         _lock_fh( fh );                 /* lock file handle */
  89.         r = _lseeki64_lk( fh, pos, mthd ); /* seek */
  90.         _unlock_fh( fh );               /* unlock file handle */
  91.  
  92.         return( r );
  93. }
  94.  
  95.  
  96. /***
  97. *__int64 _lseeki64_lk( fh, pos, mthd ) - move the file pointer
  98. *
  99. *Purpose:
  100. *       Non-locking version of _lseeki64 for internal use only.
  101. *
  102. *Entry:
  103. *
  104. *Exit:
  105. *
  106. *Exceptions:
  107. *
  108. *******************************************************************************/
  109.  
  110. __int64 __cdecl _lseeki64_lk (
  111.         int fh,
  112.         __int64 pos,
  113.         int mthd
  114.         )
  115. {
  116.         DINT newpos;                    /* new file position */
  117.         unsigned long errcode;          /* error code from API call */
  118.         HANDLE osHandle;        /* o.s. handle value */
  119.  
  120. #else  /* _MT */
  121.  
  122. __int64 __cdecl _lseeki64 (
  123.         int fh,
  124.         __int64 pos,
  125.         int mthd
  126.         )
  127. {
  128.         DINT newpos;                    /* new file position */
  129.         unsigned long errcode;          /* error code from API call */
  130.         HANDLE osHandle;        /* o.s. handle value */
  131.  
  132.         /* validate fh */
  133.  
  134.         if ( ((unsigned)fh >= (unsigned)_nhandle) ||
  135.              !(_osfile(fh) & FOPEN) )
  136.          {
  137.                 /* bad file handle */
  138.                 errno = EBADF;
  139.                 _doserrno = 0;          /* not OS error */
  140.                 return( -1i64 );
  141.         }
  142.  
  143. #endif  /* _MT */
  144.  
  145.         newpos.bigint = pos;
  146.  
  147.         /* tell OS to seek */
  148.  
  149. #if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
  150.     #error Xenix and Win32 seek constants not compatible
  151. #endif  /* SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END */
  152.  
  153.         if ((osHandle = (HANDLE)_get_osfhandle(fh)) == (HANDLE)-1)
  154.         {
  155.             errno = EBADF;
  156.                 return( -1i64 );
  157.         }
  158.  
  159.         if ( ((newpos.twoints.lowerhalf =
  160.                SetFilePointer( osHandle,
  161.                                newpos.twoints.lowerhalf,
  162.                                &(newpos.twoints.upperhalf),
  163.                                mthd )) == -1L) &&
  164.              ((errcode = GetLastError()) != NO_ERROR) )
  165.         {
  166.                 _dosmaperr( errcode );
  167.                 return( -1i64 );
  168.         }
  169.  
  170.         _osfile(fh) &= ~FEOFLAG;        /* clear the ctrl-z flag on the file */
  171.         return( newpos.bigint );        /* return */
  172. }
  173.