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.

183 lines
6.1 KiB

  1. /***
  2. *dup.c - duplicate file handles
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _dup() - duplicate file handles
  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. * 02-18-91 SRW Changed to call _free_osfhnd [_WIN32_]
  26. * 02-25-91 SRW Renamed _get_free_osfhnd to be _alloc_osfhnd [_WIN32_]
  27. * 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
  28. * 09-03-92 GJF Added explicit check for unopened handles [_WIN32_].
  29. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  30. * 09-06-94 CFW Remove Cruiser support.
  31. * 12-03-94 SKS Clean up OS/2 references
  32. * 01-04-95 GJF _WIN32_ -> _WIN32
  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. * 05-16-96 GJF Clear FNOINHERIT (new) bit on _osfile. Also, detab-ed.
  38. * 07-08-96 GJF Replaced defined(_WIN32) with !defined(_MAC), and
  39. * defined(_M_M68K) || defined(_M_MPPC) with
  40. * defined(_MAC). Also, cleaned up the format a bit.
  41. * 12-17-97 GJF Exception-safe locking.
  42. * 02-07-98 GJF Changes for Win64: use intptr_t for anything holding
  43. * a HANDLE value.
  44. * 05-17-99 PML Remove all Macintosh support.
  45. *
  46. *******************************************************************************/
  47. #include <cruntime.h>
  48. #include <oscalls.h>
  49. #include <errno.h>
  50. #include <mtdll.h>
  51. #include <io.h>
  52. #include <msdos.h>
  53. #include <internal.h>
  54. #include <stdlib.h>
  55. #ifdef _MT
  56. static int __cdecl _dup_lk(int);
  57. #endif
  58. /***
  59. *int _dup(fh) - duplicate a file handle
  60. *
  61. *Purpose:
  62. * Assigns another file handle to the file associated with the
  63. * handle fh. The next available file handle is assigned.
  64. *
  65. * Multi-thread: Be sure not to hold two file handle locks
  66. * at the same time!
  67. *
  68. *Entry:
  69. * int fh - file handle to duplicate
  70. *
  71. *Exit:
  72. * returns new file handle if successful
  73. * returns -1 (and sets errno) if fails
  74. *
  75. *Exceptions:
  76. *
  77. *******************************************************************************/
  78. int __cdecl _dup (
  79. int fh
  80. )
  81. {
  82. int newfh; /* variable for new file handle */
  83. #ifndef _MT
  84. ULONG dosretval; /* o.s. return value */
  85. char fileinfo; /* _osfile info for file */
  86. intptr_t new_osfhandle;
  87. #endif /* _MT */
  88. /* validate file handle */
  89. if ( ((unsigned)fh >= (unsigned)_nhandle) ||
  90. !(_osfile(fh) & FOPEN) )
  91. {
  92. errno = EBADF;
  93. _doserrno = 0; /* no o.s. error */
  94. return -1;
  95. }
  96. #ifndef _MT
  97. fileinfo = _osfile(fh); /* get file info for file */
  98. #endif
  99. #ifdef _MT
  100. _lock_fh(fh); /* lock file handle */
  101. __try {
  102. if ( _osfile(fh) & FOPEN )
  103. newfh = _dup_lk(fh);
  104. else {
  105. errno = EBADF;
  106. _doserrno = 0;
  107. newfh = -1;
  108. }
  109. }
  110. __finally {
  111. if ( newfh != -1 )
  112. _unlock_fh(newfh);
  113. _unlock_fh(fh);
  114. }
  115. return newfh;
  116. }
  117. static int __cdecl _dup_lk(
  118. int fh
  119. )
  120. {
  121. int newfh; /* variable for new file handle */
  122. ULONG dosretval; /* o.s. return value */
  123. char fileinfo; /* _osfile info for file */
  124. intptr_t new_osfhandle;
  125. fileinfo = _osfile(fh); /* get file info for file */
  126. if ( !(_osfile(fh) & FOPEN) )
  127. return -1;
  128. #endif /* _MT */
  129. /* create duplicate handle */
  130. if ( (newfh = _alloc_osfhnd()) == -1 )
  131. {
  132. errno = EMFILE; /* too many files error */
  133. _doserrno = 0L; /* not an OS error */
  134. _unlock_fh(fh);
  135. return -1; /* return error to caller */
  136. }
  137. /*
  138. * duplicate the file handle
  139. */
  140. if ( !(DuplicateHandle(GetCurrentProcess(),
  141. (HANDLE)_get_osfhandle(fh),
  142. GetCurrentProcess(),
  143. (PHANDLE)&new_osfhandle,
  144. 0L,
  145. TRUE,
  146. DUPLICATE_SAME_ACCESS)) )
  147. {
  148. dosretval = GetLastError();
  149. }
  150. else {
  151. _set_osfhnd(newfh, new_osfhandle);
  152. dosretval = 0;
  153. }
  154. if (dosretval) {
  155. /* o.s. error -- map and return */
  156. _dosmaperr(dosretval);
  157. return -1;
  158. }
  159. /*
  160. * copy the _osfile value, with the FNOINHERIT bit cleared
  161. */
  162. _osfile(newfh) = fileinfo & ~FNOINHERIT;
  163. return newfh;
  164. }