Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.4 KiB

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