Source code of Windows XP (NT5)
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.

176 lines
6.0 KiB

  1. /***
  2. *close.c - close file handle for Windows NT
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _close() - close a file handle
  8. *
  9. *Revision History:
  10. * 06-09-89 PHG Module created, based on asm version
  11. * 03-12-90 GJF Made calling type _CALLTYPE2 (for now), added #include
  12. * <cruntime.h> and fixed the copyright. Also, cleaned up
  13. * the formatting a bit.
  14. * 04-03-90 GJF Now CALLTYPE1.
  15. * 07-24-90 SBM Removed '32' from API names
  16. * 08-14-90 SBM Compiles cleanly with -W3
  17. * 09-28-90 GJF New-style function declarator.
  18. * 12-04-90 GJF Appended Win32 version onto the source with #ifdef-s.
  19. * It is enough different that there is little point in
  20. * trying to more closely merge the two versions.
  21. * 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
  22. * 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo
  23. * 01-16-91 GJF ANSI naming.
  24. * 02-07-91 SRW Changed to call _get_osfhandle [_WIN32_]
  25. * 04-09-91 PNT Added _MAC_ conditional
  26. * 07-17-91 GJF Syntax error in multi-thread build [_WIN32_]
  27. * 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
  28. * 02-21-92 GJF Removed bogus _unlock_fh() call.
  29. * 03-22-93 GJF Check for STDOUT and STDERR being mapped to the same
  30. * OS file handle. Also, purged Cruiser support.
  31. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  32. * 09-06-94 CFW Replace MTHREAD with _MT.
  33. * 02-15-95 GJF Appended Mac version of source file (somewhat cleaned
  34. * up), with appropriate #ifdef-s.
  35. * 06-11-95 GJF Replaced _osfile[] with _osfile() (macro referencing
  36. * field in ioinfo struct).
  37. * 06-26-95 GJF Added check that the file handle is open.
  38. * 07-08-96 GJF Replaced defined(_WIN32) with !defined(_MAC), and
  39. * defined(_M_M68K) || defined(_M_MPPC) with
  40. * defined(_MAC). Also, detab-ed and cleaned up the
  41. * format a bit.
  42. * 07-23-96 GJF Reset the lowio info even when CloseHandle fails.
  43. * Specifically check for underlying OS HANDLE value of
  44. * INVALID_HANDLE_VALUE.
  45. * 08-01-96 RDK For PMac, if file with _O_TEMPORARY flag, try to delete
  46. * after the close.
  47. * 12-17-97 GJF Exception-safe locking.
  48. * 02-07-98 GJF Changes for Win64: changed long cast to intptr_t cast.
  49. * 05-17-99 PML Remove all Macintosh support.
  50. *
  51. *******************************************************************************/
  52. #include <cruntime.h>
  53. #include <oscalls.h>
  54. #include <io.h>
  55. #include <mtdll.h>
  56. #include <errno.h>
  57. #include <stdlib.h>
  58. #include <msdos.h>
  59. #include <internal.h>
  60. /***
  61. *int _close(fh) - close a file handle
  62. *
  63. *Purpose:
  64. * Closes the file associated with the file handle fh.
  65. *
  66. *Entry:
  67. * int fh - file handle to close
  68. *
  69. *Exit:
  70. * returns 0 if successful, -1 (and sets errno) if fails
  71. *
  72. *Exceptions:
  73. *
  74. *******************************************************************************/
  75. #ifdef _MT
  76. /* define normal version that locks/unlocks, validates fh */
  77. int __cdecl _close (
  78. int fh
  79. )
  80. {
  81. int r; /* return value */
  82. /* validate file handle */
  83. if ( ((unsigned)fh >= (unsigned)_nhandle) ||
  84. !(_osfile(fh) & FOPEN) )
  85. {
  86. /* bad file handle, set errno and abort */
  87. errno = EBADF;
  88. _doserrno = 0;
  89. return -1;
  90. }
  91. _lock_fh(fh); /* lock file */
  92. __try {
  93. if ( _osfile(fh) & FOPEN )
  94. r = _close_lk(fh);
  95. else {
  96. errno = EBADF;
  97. r = -1;
  98. }
  99. }
  100. __finally {
  101. _unlock_fh(fh); /* unlock the file */
  102. }
  103. return r;
  104. }
  105. /* now define version that doesn't lock/unlock, validate fh */
  106. int __cdecl _close_lk (
  107. int fh
  108. )
  109. {
  110. DWORD dosretval;
  111. #else
  112. /* now define normal version */
  113. int __cdecl _close (
  114. int fh
  115. )
  116. {
  117. DWORD dosretval;
  118. /* validate file handle */
  119. if ( ((unsigned)fh >= (unsigned)_nhandle) ||
  120. !(_osfile(fh) & FOPEN) )
  121. {
  122. /* bad file handle, set errno and abort */
  123. errno = EBADF;
  124. _doserrno = 0; /* no o.s. error */
  125. return -1;
  126. }
  127. #endif
  128. /*
  129. * Close the underlying OS file handle. Special cases:
  130. * 1. If _get_osfhandle(fh) is INVALID_HANDLE_VALUE, don't try
  131. * to actually close it. Just reset the lowio info so the
  132. * handle can be reused. The standard handles are setup like
  133. * this in Windows app, or a background app.
  134. * 2. If fh is STDOUT or STDERR, and if STDOUT and STDERR are
  135. * mapped to the same OS file handle, skip the CloseHandle
  136. * is skipped (without error). STDOUT and STDERR are the only
  137. * handles for which this support is provided. Other handles
  138. * are mapped to the same OS file handle only at the
  139. * programmer's risk.
  140. */
  141. if ( (_get_osfhandle(fh) == (intptr_t)INVALID_HANDLE_VALUE) ||
  142. ( ((fh == 1) || (fh == 2)) &&
  143. (_get_osfhandle(1) == _get_osfhandle(2)) ) ||
  144. CloseHandle( (HANDLE)_get_osfhandle(fh) ) )
  145. {
  146. dosretval = 0L;
  147. }
  148. else
  149. dosretval = GetLastError();
  150. _free_osfhnd(fh);
  151. _osfile(fh) = 0; /* clear file flags */
  152. if (dosretval) {
  153. /* OS error */
  154. _dosmaperr(dosretval);
  155. return -1;
  156. }
  157. return 0; /* good return */
  158. }