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

  1. /***
  2. *fdopen.c - open a file descriptor as stream
  3. *
  4. *       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines _fdopen() - opens a file descriptor as a stream, thus allowing
  8. *       buffering, etc.
  9. *
  10. *******************************************************************************/
  11.  
  12. #include <cruntime.h>
  13. #include <msdos.h>
  14. #include <stdio.h>
  15. #include <file2.h>
  16. #include <dbgint.h>
  17. #include <internal.h>
  18. #include <mtdll.h>
  19. #include <tchar.h>
  20.  
  21. /***
  22. *FILE *_fdopen(filedes, mode) - open a file descriptor as a stream
  23. *
  24. *Purpose:
  25. *       associates a stream with a file handle, thus allowing buffering, etc.
  26. *       The mode must be specified and must be compatible with the mode
  27. *       the file was opened with in the low level open.
  28. *
  29. *Entry:
  30. *       int filedes - handle referring to open file
  31. *       _TSCHAR *mode - file mode to use ("r", "w", "a", etc.)
  32. *
  33. *Exit:
  34. *       returns stream pointer and sets FILE struct fields if successful
  35. *       returns NULL if fails
  36. *
  37. *Exceptions:
  38. *
  39. *******************************************************************************/
  40.  
  41. FILE * __cdecl _tfdopen (
  42.         int filedes,
  43.         REG2 const _TSCHAR *mode
  44.         )
  45. {
  46.         REG1 FILE *stream;
  47.         int whileflag, tbflag, cnflag;
  48.  
  49.         _ASSERTE(mode != NULL);
  50.  
  51. #if defined (_WIN32)
  52.  
  53.         _ASSERTE((unsigned)filedes < (unsigned)_nhandle);
  54.         _ASSERTE(_osfile(filedes) & FOPEN);
  55.  
  56.         if ( ((unsigned)filedes >= (unsigned)_nhandle) ||
  57.              !(_osfile(filedes) & FOPEN) )
  58.             return(NULL);
  59.  
  60. #else  /* defined (_WIN32) */
  61.  
  62.  
  63. #if defined (_M_MPPC) || defined (_M_M68K)
  64.  
  65.         _ASSERTE((unsigned)filedes < (unsigned)_nfile);
  66.         _ASSERTE(_osfile[filedes] & FOPEN);
  67.  
  68.         if ( ((unsigned)filedes >= (unsigned)_nfile) ||
  69.              !(_osfile[filedes] & FOPEN) )
  70.             return(NULL);
  71.  
  72. #endif  /* defined (_M_MPPC) || defined (_M_M68K) */
  73.  
  74.  
  75. #endif  /* defined (_WIN32) */
  76.  
  77.  
  78.         /* Find a free stream; stream is returned 'locked'. */
  79.  
  80.         if ((stream = _getstream()) == NULL)
  81.             return(NULL);
  82.  
  83.         /* First character must be 'r', 'w', or 'a'. */
  84.  
  85.         switch (*mode) {
  86.             case _T('r'):
  87.                 stream->_flag = _IOREAD;
  88.                 break;
  89.             case _T('w'):
  90.             case _T('a'):
  91.                 stream->_flag = _IOWRT;
  92.                 break;
  93.             default:
  94.                 stream = NULL;  /* error */
  95.                 goto done;
  96.                 break;
  97.         }
  98.  
  99.         /* There can be up to three more optional characters:
  100.            (1) A single '+' character,
  101.            (2) One of 'b' and 't' and
  102.            (3) One of 'c' and 'n'.
  103.  
  104.            Note that currently, the 't' and 'b' flags are syntax checked
  105.            but ignored.  'c' and 'n', however, are correctly supported.
  106.         */
  107.  
  108.         whileflag=1;
  109.         tbflag=cnflag=0;
  110.         stream->_flag |= _commode;
  111.  
  112.         while(*++mode && whileflag)
  113.             switch(*mode) {
  114.  
  115.                 case _T('+'):
  116.                     if (stream->_flag & _IORW)
  117.                         whileflag=0;
  118.                     else {
  119.                         stream->_flag |= _IORW;
  120.                         stream->_flag &= ~(_IOREAD | _IOWRT);
  121.                     }
  122.                     break;
  123.  
  124.                 case _T('b'):
  125.                 case _T('t'):
  126.                     if (tbflag)
  127.                         whileflag=0;
  128.                     else
  129.                         tbflag=1;
  130.                     break;
  131.  
  132.                 case _T('c'):
  133.                     if (cnflag)
  134.                         whileflag = 0;
  135.                     else {
  136.                         cnflag = 1;
  137.                         stream->_flag |= _IOCOMMIT;
  138.                     }
  139.                     break;
  140.  
  141.                 case _T('n'):
  142.                     if (cnflag)
  143.                         whileflag = 0;
  144.                     else {
  145.                         cnflag = 1;
  146.                         stream->_flag &= ~_IOCOMMIT;
  147.                     }
  148.                     break;
  149.  
  150.                 default:
  151.                     whileflag=0;
  152.                     break;
  153.             }
  154.  
  155. #ifndef CRTDLL
  156.         _cflush++;  /* force library pre-termination procedure */
  157. #endif  /* CRTDLL */
  158.  
  159.         stream->_file = filedes;
  160.  
  161. #if defined (_M_MPPC) || defined (_M_M68K)
  162.         if ( ( ( _osfile[filedes] & FRDONLY ) && (stream->_flag & (_IORW | _IOWRT)) ) ||
  163.             ( ( _osfile[filedes] & FWRONLY ) && (stream->_flag & (_IORW | _IOREAD)) ) )
  164.         {
  165.             stream->_flag = 0;   /* stream not used */
  166.             return(NULL);
  167.         }
  168. #endif  /* defined (_M_MPPC) || defined (_M_M68K) */
  169.  
  170. /* Common return */
  171.  
  172. done:
  173.         _unlock_str(stream);
  174.         return(stream);
  175. }
  176.