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

  1. /***
  2. *fclose.c - close a file
  3. *
  4. *       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines fclose() - close an open file
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <cruntime.h>
  12. #include <stdio.h>
  13. #include <file2.h>
  14. #include <string.h>
  15. #include <io.h>
  16. #include <stdlib.h>
  17. #include <internal.h>
  18. #include <mtdll.h>
  19. #include <dbgint.h>
  20.  
  21. #if defined (_M_MPPC) || defined (_M_M68K)
  22. #include <macos\osutils.h>
  23. #include <macos\files.h>
  24. #include <macos\errors.h>
  25. #include <macos\gestalte.h>
  26. #include <macos\traps.h>
  27. #include <macos\toolutil.h>
  28. #include <macos\folders.h>
  29. #endif  /* defined (_M_MPPC) || defined (_M_M68K) */
  30.  
  31.  
  32. /***
  33. *int fclose(stream) - close a stream
  34. *
  35. *Purpose:
  36. *       Flushes and closes a stream and frees any buffer associated
  37. *       with that stream, unless it was set with setbuf.
  38. *
  39. *Entry:
  40. *       FILE *stream - stream to close
  41. *
  42. *Exit:
  43. *       returns 0 if OK, EOF if fails (can't _flush, not a FILE, not open, etc.)
  44. *       closes the file -- affecting FILE structure
  45. *
  46. *Exceptions:
  47. *
  48. *******************************************************************************/
  49.  
  50. #ifdef _MT
  51.  
  52. int __cdecl fclose (
  53.         FILE *stream
  54.         )
  55. {
  56.         int result = EOF;
  57.  
  58.         _ASSERTE(stream != NULL);
  59.  
  60.         /* If stream is a string, simply clear flag and return EOF */
  61.         if (stream->_flag & _IOSTRG)
  62.                 stream->_flag = 0;  /* IS THIS REALLY NEEDED ??? */
  63.  
  64.         /* Stream is a real file. */
  65.         else {
  66.                 _lock_str(stream);
  67.                 result = _fclose_lk(stream);
  68.                 _unlock_str(stream);
  69.         }
  70.  
  71.         return(result);
  72. }
  73.  
  74. /***
  75. *int _fclose_lk() - close a stream (lock already held)
  76. *
  77. *Purpose:
  78. *       Core fclose() routine; assumes caller has stream lock held.
  79. *
  80. *       [See fclose() above for more information.]
  81. *
  82. *Entry:
  83. *
  84. *Exit:
  85. *
  86. *Exceptions:
  87. *
  88. *******************************************************************************/
  89.  
  90. int __cdecl _fclose_lk (
  91.         FILE *str
  92.         )
  93. {
  94.         REG1 FILE *stream;
  95.         REG2 int result = EOF;
  96.  
  97.         /* Init near stream pointer */
  98.         stream = str;
  99.  
  100. #else  /* _MT */
  101.  
  102. int __cdecl fclose (
  103.         FILE *str
  104.         )
  105. {
  106.         REG1 FILE *stream;
  107.         REG2 int result = EOF;
  108.  
  109.         /* Init near stream pointer */
  110.         stream = str;
  111.  
  112.         if (stream->_flag & _IOSTRG) {
  113.                 stream->_flag = 0;
  114.                 return(EOF);
  115.         }
  116.  
  117. #endif  /* _MT */
  118.  
  119.         _ASSERTE(str != NULL);
  120.  
  121.         if (inuse(stream)) {
  122.  
  123.                 /* Stream is in use:
  124.                        (1) flush stream
  125.                        (2) free the buffer
  126.                        (3) close the file
  127.                        (4) delete the file if temporary
  128.                 */
  129.  
  130.                 result = _flush(stream);
  131.                 _freebuf(stream);
  132.  
  133.                 if (_close(_fileno(stream)) < 0)
  134.                         result = EOF;
  135.  
  136.                 else if ( stream->_tmpfname != NULL ) {
  137.                         /*
  138.                          * temporary file (i.e., one created by tmpfile()
  139.                          * call). delete, if necessary (don't have to on
  140.                          * Windows NT because it was done by the system when
  141.                          * the handle was closed). also, free up the heap
  142.                          * block holding the pathname.
  143.                          */
  144.  
  145. #if defined (_M_MPPC) || defined (_M_M68K)
  146.                         if ( _unlink(stream->_tmpfname) )
  147.                                 result = EOF;
  148. #endif  /* defined (_M_MPPC) || defined (_M_M68K) */
  149.                         _free_crt(stream->_tmpfname);
  150.                 stream->_tmpfname = NULL;
  151.                 }
  152.  
  153.         }
  154.  
  155.         stream->_flag = 0;
  156.         return(result);
  157. }
  158.