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

  1. /***
  2. *_open.c - open a stream, with string mode
  3. *
  4. *       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       defines _openfile() - opens a stream, with string arguments for mode
  8. *
  9. *******************************************************************************/
  10.  
  11. #ifdef _WIN32
  12.  
  13.  
  14. #include <cruntime.h>
  15. #include <stdio.h>
  16. #include <fcntl.h>
  17. #include <file2.h>
  18. #include <io.h>
  19. #include <dbgint.h>
  20. #include <internal.h>
  21. #include <tchar.h>
  22.  
  23. #define CMASK   0644    /* rw-r--r-- */
  24. #define P_CMASK 0666    /* different for Posix */
  25.  
  26. /***
  27. *FILE *_openfile(filename, mode, shflag, stream) - open a file with string
  28. *       mode and file sharing flag.
  29. *
  30. *Purpose:
  31. *       parse the string, looking for exactly one of {rwa}, at most one '+',
  32. *       at most one of {tb}, at most one of {cn}, at most one of {SR}, at most
  33. *       one 'T', and at most one 'D'. pass the result on as an int containing
  34. *       flags of what was found. open a file with proper mode if permissions
  35. *       allow. buffer not allocated until first i/o call is issued. intended
  36. *       for use inside library only
  37. *
  38. *Entry:
  39. *       char *filename - file to open
  40. *       char *mode - mode to use (see above)
  41. *       int shflag - file sharing flag
  42. *       FILE *stream - stream to use for file
  43. *
  44. *Exit:
  45. *       set stream's fields, and causes system file management by system calls
  46. *       returns stream or NULL if fails
  47. *
  48. *Exceptions:
  49. *
  50. *******************************************************************************/
  51.  
  52. #ifdef _UNICODE
  53. FILE * __cdecl _wopenfile (
  54. #else  /* _UNICODE */
  55. FILE * __cdecl _openfile (
  56. #endif  /* _UNICODE */
  57.         const _TSCHAR *filename,
  58.         REG3 const _TSCHAR *mode,
  59.         int shflag,
  60.         FILE *str
  61.         )
  62. {
  63.         REG2 int modeflag;
  64.         int streamflag = _commode;
  65.         int commodeset = 0;
  66.         int scanset    = 0;
  67.         int whileflag;
  68.         int filedes;
  69.         REG1 FILE *stream;
  70.  
  71.         _ASSERTE(filename != NULL);
  72.         _ASSERTE(mode != NULL);
  73.         _ASSERTE(str != NULL);
  74.  
  75.         /* Parse the user's specification string as set flags in
  76.                (1) modeflag - system call flags word
  77.                (2) streamflag - stream handle flags word. */
  78.  
  79.         /* First mode character must be 'r', 'w', or 'a'. */
  80.  
  81.         switch (*mode) {
  82.         case _T('r'):
  83.                 modeflag = _O_RDONLY;
  84.                 streamflag |= _IOREAD;
  85.                 break;
  86.         case _T('w'):
  87.                 modeflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
  88.                 streamflag |= _IOWRT;
  89.                 break;
  90.         case _T('a'):
  91.                 modeflag = _O_WRONLY | _O_CREAT | _O_APPEND;
  92.                 streamflag |= _IOWRT;
  93.                 break;
  94.         default:
  95.                 return(NULL);
  96.                 break;
  97.         }
  98.  
  99.         /* There can be up to three more optional mode characters:
  100.            (1) A single '+' character,
  101.            (2) One of 't' and 'b' and
  102.            (3) One of 'c' and 'n'.
  103.         */
  104.  
  105.         whileflag=1;
  106.  
  107.         while(*++mode && whileflag)
  108.                 switch(*mode) {
  109.  
  110.                 case _T('+'):
  111.                         if (modeflag & _O_RDWR)
  112.                                 whileflag=0;
  113.                         else {
  114.                                 modeflag |= _O_RDWR;
  115.                                 modeflag &= ~(_O_RDONLY | _O_WRONLY);
  116.                                 streamflag |= _IORW;
  117.                                 streamflag &= ~(_IOREAD | _IOWRT);
  118.                         }
  119.                         break;
  120.  
  121.                 case _T('b'):
  122.                         if (modeflag & (_O_TEXT | _O_BINARY))
  123.                                 whileflag=0;
  124.                         else
  125.                                 modeflag |= _O_BINARY;
  126.                         break;
  127.  
  128.                 case _T('t'):
  129.                         if (modeflag & (_O_TEXT | _O_BINARY))
  130.                                 whileflag=0;
  131.                         else
  132.                                 modeflag |= _O_TEXT;
  133.                         break;
  134.  
  135.                 case _T('c'):
  136.                         if (commodeset)
  137.                                 whileflag=0;
  138.                         else {
  139.                                 commodeset = 1;
  140.                                 streamflag |= _IOCOMMIT;
  141.                         }
  142.                         break;
  143.  
  144.                 case _T('n'):
  145.                         if (commodeset)
  146.                                 whileflag=0;
  147.                         else {
  148.                                 commodeset = 1;
  149.                                 streamflag &= ~_IOCOMMIT;
  150.                         }
  151.                         break;
  152.  
  153.                 case _T('S'):
  154.                         if (scanset)
  155.                                 whileflag=0;
  156.                         else {
  157.                                 scanset = 1;
  158.                                 modeflag |= _O_SEQUENTIAL;
  159.                         }
  160.                         break;
  161.  
  162.                 case _T('R'):
  163.                         if (scanset)
  164.                                 whileflag=0;
  165.                         else {
  166.                                 scanset = 1;
  167.                                 modeflag |= _O_RANDOM;
  168.                         }
  169.                         break;
  170.  
  171.                 case _T('T'):
  172.                         if (modeflag & _O_SHORT_LIVED)
  173.                                 whileflag=0;
  174.                         else
  175.                                 modeflag |= _O_SHORT_LIVED;
  176.                         break;
  177.  
  178.                 case _T('D'):
  179.                         if (modeflag & _O_TEMPORARY)
  180.                                 whileflag=0;
  181.                         else
  182.                                 modeflag |= _O_TEMPORARY;
  183.                         break;
  184.  
  185.                 default:
  186.                         whileflag=0;
  187.                         break;
  188.                 }
  189.  
  190.         /* Try to open the file.  Note that if neither 't' nor 'b' is
  191.            specified, _sopen will use the default. */
  192.  
  193.         if ((filedes = _tsopen(filename, modeflag, shflag, CMASK)) < 0)
  194.                 return(NULL);
  195.  
  196.         /* Set up the stream data base. */
  197. #ifndef CRTDLL
  198.         _cflush++;  /* force library pre-termination procedure */
  199. #endif  /* CRTDLL */
  200.         /* Init pointers */
  201.         stream = str;
  202.  
  203.         stream->_flag = streamflag;
  204.         stream->_cnt = 0;
  205.         stream->_tmpfname = stream->_base = stream->_ptr = NULL;
  206.  
  207.         stream->_file = filedes;
  208.  
  209.         return(stream);
  210. }
  211.  
  212.  
  213. #else  /* _WIN32 */
  214.  
  215. #if defined (_M_MPPC) || defined (_M_M68K)
  216.  
  217.  
  218. #include <cruntime.h>
  219. #include <stdio.h>
  220. #include <fcntl.h>
  221. #include <file2.h>
  222. #include <io.h>
  223. #include <dbgint.h>
  224. #include <internal.h>
  225.  
  226. #define CMASK   0644    /* rw-r--r-- */
  227.  
  228. /***
  229. *FILE *_openfile(filename, mode, shflag, stream) - open a file with string
  230. *       mode and file sharing flag.
  231. *
  232. *Purpose:
  233. *       parse the string, looking for exactly one of {rwa}, at most one '+',
  234. *       at most one of {tb} and at most one of {cn}. pass the result on as
  235. *       an int containing flags of what was found. open a file with proper
  236. *       mode if permissions allow. buffer not allocated until first i/o call
  237. *       is issued. intended for use inside library only
  238. *
  239. *Entry:
  240. *       char *filename - file to open
  241. *       char *mode - mode to use (see above)
  242. *       int shflag - file sharing flag
  243. *       FILE *stream - stream to use for file
  244. *
  245. *Exit:
  246. *       set stream's fields, and causes system file management by system calls
  247. *       returns stream or NULL if fails
  248. *
  249. *Exceptions:
  250. *
  251. *******************************************************************************/
  252.  
  253. FILE * __cdecl _openfile (
  254.         const char *filename,
  255.         REG3 const char *mode,
  256.         int shflag,
  257.         FILE *str
  258.         )
  259. {
  260.         REG2 int modeflag;
  261.         int streamflag = _commode;
  262.         int commodeset = 0;
  263.         int whileflag;
  264.         int filedes;
  265.         REG1 FILE *stream;
  266.  
  267.         _ASSERTE(filename != NULL);
  268.         _ASSERTE(mode != NULL);
  269.         _ASSERTE(str != NULL);
  270.  
  271.         /* Parse the user's specification string as set flags in
  272.                (1) modeflag - system call flags word
  273.                (2) streamflag - stream handle flags word. */
  274.  
  275.         /* First mode character must be 'r', 'w', or 'a'. */
  276.  
  277.         switch (*mode) {
  278.         case 'r':
  279.                 modeflag = _O_RDONLY;
  280.                 streamflag |= _IOREAD;
  281.                 break;
  282.         case 'w':
  283.                 modeflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
  284.                 streamflag |= _IOWRT;
  285.                 break;
  286.         case 'a':
  287.                 modeflag = _O_WRONLY | _O_CREAT | _O_APPEND;
  288.                 streamflag |= _IOWRT;
  289.                 break;
  290.         default:
  291.                 return(NULL);
  292.                 break;
  293.         }
  294.  
  295.         /* There can be up to three more optional mode characters:
  296.            (1) A single '+' character,
  297.            (2) One of 't' and 'b' and
  298.            (3) One of 'c' and 'n'.
  299.         */
  300.  
  301.         whileflag=1;
  302.  
  303.         while(*++mode && whileflag)
  304.                 switch(*mode) {
  305.  
  306.                 case '+':
  307.                         if (modeflag & _O_RDWR)
  308.                                 whileflag=0;
  309.                         else {
  310.                                 modeflag |= _O_RDWR;
  311.                                 modeflag &= ~(_O_RDONLY | _O_WRONLY);
  312.                                 streamflag |= _IORW;
  313.                                 streamflag &= ~(_IOREAD | _IOWRT);
  314.                         }
  315.                         break;
  316.                 case 't':
  317.                         if (modeflag & (_O_TEXT | _O_BINARY))
  318.                                 whileflag=0;
  319.                         else
  320.                                 modeflag |= _O_TEXT;
  321.                         break;
  322.  
  323.                 case 'b':
  324.                         if (modeflag & (_O_TEXT | _O_BINARY))
  325.                                 whileflag=0;
  326.                         else
  327.                                 modeflag |= _O_BINARY;
  328.                         break;
  329.                 case 'c':
  330.                         if (commodeset)
  331.                                 whileflag=0;
  332.                         else {
  333.                                 commodeset = 1;
  334.                                 streamflag |= _IOCOMMIT;
  335.                         }
  336.                         break;
  337.  
  338.                 case 'n':
  339.                         if (commodeset)
  340.                                 whileflag=0;
  341.                         else {
  342.                                 commodeset = 1;
  343.                                 streamflag &= ~_IOCOMMIT;
  344.                         }
  345.                         break;
  346.                 default:
  347.                         whileflag=0;
  348.                         break;
  349.                 }
  350.  
  351.         /* Try to open the file.  Note that if neither 't' nor 'b' is
  352.            specified, _sopen will use the default. */
  353.  
  354.         if ((filedes = _sopen(filename, modeflag, shflag, CMASK)) < 0)
  355.                 return(NULL);
  356.  
  357.         /* Set up the stream data base. */
  358.  
  359. #ifndef CRTDLL
  360.         /* force library pre-termination procedure */
  361.         _cflush++;
  362. #endif  /* CRTDLL */
  363.  
  364.         /* Init pointers */
  365.         stream = str;
  366.  
  367.         stream->_flag = streamflag;
  368.         stream->_cnt = 0;
  369.         stream->_tmpfname = stream->_base = stream->_ptr = NULL;
  370.         stream->_file = filedes;
  371.  
  372.         return(stream);
  373. }
  374.  
  375.  
  376. #endif  /* defined (_M_MPPC) || defined (_M_M68K) */
  377.  
  378. #endif  /* _WIN32 */
  379.