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

  1. /***
  2. *dup.c - duplicate file handles
  3. *
  4. *       Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines _dup() - duplicate file handles
  8. *
  9. *******************************************************************************/
  10.  
  11. #ifndef _MAC
  12.  
  13.  
  14. #include <cruntime.h>
  15. #include <oscalls.h>
  16. #include <errno.h>
  17. #include <mtdll.h>
  18. #include <io.h>
  19. #include <msdos.h>
  20. #include <internal.h>
  21. #include <stdlib.h>
  22.  
  23. /***
  24. *int _dup(fh) - duplicate a file handle
  25. *
  26. *Purpose:
  27. *       Assigns another file handle to the file associated with the
  28. *       handle fh.  The next available file handle is assigned.
  29. *
  30. *       Multi-thread: Be sure not to hold two file handle locks
  31. *       at the same time!
  32. *
  33. *Entry:
  34. *       int fh - file handle to duplicate
  35. *
  36. *Exit:
  37. *       returns new file handle if successful
  38. *       returns -1 (and sets errno) if fails
  39. *
  40. *Exceptions:
  41. *
  42. *******************************************************************************/
  43.  
  44. int __cdecl _dup (
  45.         int fh
  46.         )
  47. {
  48.         ULONG dosretval;                /* o.s. return value */
  49.         int newfh;                      /* variable for new file handle */
  50.         char fileinfo;                  /* _osfile info for file */
  51.         long new_osfhandle;
  52.  
  53.         /* validate file handle */
  54.         if ( ((unsigned)fh >= (unsigned)_nhandle) ||
  55.              !(_osfile(fh) & FOPEN) )
  56.         {
  57.                 errno = EBADF;
  58.                 _doserrno = 0;  /* no o.s. error */
  59.                 return -1;
  60.         }
  61.  
  62.         _lock_fh(fh);                   /* lock file handle */
  63.         fileinfo = _osfile(fh);         /* get file info for file */
  64.  
  65.         /* create duplicate handle */
  66.  
  67.         if ( (newfh = _alloc_osfhnd()) == -1 )
  68.         {
  69.                 errno = EMFILE;         /* too many files error */
  70.                 _doserrno = 0L;         /* not an OS error */
  71.                 _unlock_fh(fh);
  72.                 return -1;              /* return error to caller */
  73.         }
  74.  
  75.         /*
  76.          * duplicate the file handle
  77.          */
  78.         if ( !(DuplicateHandle(GetCurrentProcess(),
  79.                                (HANDLE)_get_osfhandle(fh),
  80.                                GetCurrentProcess(),
  81.                                (PHANDLE)&new_osfhandle,
  82.                                0L,
  83.                                TRUE,
  84.                                DUPLICATE_SAME_ACCESS)) )
  85.         {
  86.                 dosretval = GetLastError();
  87.         }
  88.         else {
  89.                 _set_osfhnd(newfh, new_osfhandle);
  90.                 dosretval = 0;
  91.         }
  92.  
  93.         _unlock_fh(newfh);
  94.  
  95.         _unlock_fh(fh);                 /* unlock file handle */
  96.  
  97.         if (dosretval) {
  98.                 /* o.s. error -- map and return */
  99.                 _dosmaperr(dosretval);
  100.                 return -1;
  101.         }
  102.  
  103.         /*
  104.          * copy the _osfile value, with the FNOINHERIT bit cleared
  105.          */
  106.         _osfile(newfh) = fileinfo & ~FNOINHERIT;
  107.  
  108.         return newfh;
  109. }
  110.  
  111.  
  112. #else  /* _MAC */
  113.  
  114.  
  115. #include <cruntime.h>
  116. #include <errno.h>
  117. #include <io.h>
  118. #include <internal.h>
  119. #include <stdlib.h>
  120. #include <msdos.h>
  121.  
  122. /***
  123. *int _dup(fh) - duplicate a file handle
  124. *
  125. *Purpose:
  126. *       Assigns another file handle to the file associated with the
  127. *       handle fh.  The next available file handle is assigned.
  128. *
  129. *Entry:
  130. *       int fh - file handle to duplicate
  131. *
  132. *Exit:
  133. *       returns new file handle if successful
  134. *       returns -1 (and sets errno) if fails
  135. *
  136. *Exceptions:
  137. *
  138. *******************************************************************************/
  139.  
  140. int __cdecl _dup (
  141.         int fh
  142.         )
  143. {
  144.  
  145.         int fhNew;
  146.  
  147.         /* get a file handle*/
  148.         for (fhNew=0; fhNew <_nfile; fhNew++)
  149.         {
  150.                 if (!(_osfile[fhNew] & FOPEN))
  151.                 {
  152.                         break;
  153.                 }
  154.         }
  155.         if (fhNew >= _nfile)
  156.         {
  157.                 errno = EMFILE;
  158.                 _macerrno = 0;
  159.                 return -1;
  160.         }
  161.  
  162.         return __dupx(fh, fhNew);
  163. }
  164.  
  165.  
  166. #endif  /* _MAC */
  167.