Source code of Windows XP (NT5)
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.

280 lines
9.2 KiB

  1. /***
  2. *_open.c - open a stream, with string mode
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _openfile() - opens a stream, with string arguments for mode
  8. *
  9. *Revision History:
  10. * 09-02-83 RN initial version
  11. * 03-02-87 JCR made _openfile recognize "wb+" as equal to "w+b", etc.
  12. * got rid of intermediate _openfile flags (internal) and
  13. * now go straight from mode string to open system call
  14. * and system->_flags.
  15. * 09-28-87 JCR Corrected _iob2 indexing (now uses _iob_index() macro).
  16. * 02-21-88 SKS Removed #ifdef IBMC20
  17. * 06-06-88 JCR Optimized _iob2 references
  18. * 06-10-88 JCR Use near pointer to reference _iob[] entries
  19. * 08-19-88 GJF Initial adaption for the 386.
  20. * 11-14-88 GJF Added shflag (file sharing flag) parameter, also some
  21. * cleanup (now specific to the 386).
  22. * 08-17-89 GJF Clean up, now specific to OS/2 2.0 (i.e., 386 flat
  23. * model). Also fixed copyright and indents.
  24. * 02-15-90 GJF _iob[], _iob2[] merge. Also, fixed copyright.
  25. * 03-16-90 GJF Made calling type _CALLTYPE1, added #include
  26. * <cruntime.h> and removed #include <register.h>.
  27. * 03-27-90 GJF Added const qualifier to types of filename and mode.
  28. * Added #include <io.h>.
  29. * 07-11-90 SBM Added support for 'c' and 'n' flags
  30. * 07-23-90 SBM Replaced <assertm.h> by <assert.h>
  31. * 10-03-90 GJF New-style function declarator.
  32. * 01-18-91 GJF ANSI naming.
  33. * 03-11-92 GJF Replaced __tmpnum field with _tmpfname field for
  34. * Win32.
  35. * 03-25-92 DJM POSIX support.
  36. * 08-26-92 GJF Fixed POSIX support.
  37. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  38. * 05-24-93 PML Added support for 'D', 'R', 'S' and 'T' flags
  39. * 11-01-93 CFW Enable Unicode variant, rip out CRUISER.
  40. * 04-05-94 GJF #ifdef-ed out _cflush reference for msvcrt*.dll, it
  41. * is unnecessary.
  42. * 02-06-94 CFW assert -> _ASSERTE.
  43. * 02-17-95 GJF Appended Mac version of source file (somewhat cleaned
  44. * up), with appropriate #ifdef-s.
  45. * 05-17-99 PML Remove all Macintosh support.
  46. *
  47. *******************************************************************************/
  48. #include <cruntime.h>
  49. #include <stdio.h>
  50. #include <fcntl.h>
  51. #include <file2.h>
  52. #include <io.h>
  53. #include <dbgint.h>
  54. #include <internal.h>
  55. #include <tchar.h>
  56. #define CMASK 0644 /* rw-r--r-- */
  57. #define P_CMASK 0666 /* different for Posix */
  58. /***
  59. *FILE *_openfile(filename, mode, shflag, stream) - open a file with string
  60. * mode and file sharing flag.
  61. *
  62. *Purpose:
  63. * parse the string, looking for exactly one of {rwa}, at most one '+',
  64. * at most one of {tb}, at most one of {cn}, at most one of {SR}, at most
  65. * one 'T', and at most one 'D'. pass the result on as an int containing
  66. * flags of what was found. open a file with proper mode if permissions
  67. * allow. buffer not allocated until first i/o call is issued. intended
  68. * for use inside library only
  69. *
  70. *Entry:
  71. * char *filename - file to open
  72. * char *mode - mode to use (see above)
  73. * int shflag - file sharing flag
  74. * FILE *stream - stream to use for file
  75. *
  76. *Exit:
  77. * set stream's fields, and causes system file management by system calls
  78. * returns stream or NULL if fails
  79. *
  80. *Exceptions:
  81. *
  82. *******************************************************************************/
  83. #ifdef _UNICODE
  84. FILE * __cdecl _wopenfile (
  85. #else
  86. FILE * __cdecl _openfile (
  87. #endif
  88. const _TSCHAR *filename,
  89. REG3 const _TSCHAR *mode,
  90. #ifndef _POSIX_
  91. int shflag,
  92. #endif
  93. FILE *str
  94. )
  95. {
  96. REG2 int modeflag;
  97. #ifdef _POSIX_
  98. int streamflag = 0;
  99. #else
  100. int streamflag = _commode;
  101. int commodeset = 0;
  102. int scanset = 0;
  103. #endif
  104. int whileflag;
  105. int filedes;
  106. REG1 FILE *stream;
  107. _ASSERTE(filename != NULL);
  108. _ASSERTE(mode != NULL);
  109. _ASSERTE(str != NULL);
  110. /* Parse the user's specification string as set flags in
  111. (1) modeflag - system call flags word
  112. (2) streamflag - stream handle flags word. */
  113. /* First mode character must be 'r', 'w', or 'a'. */
  114. switch (*mode) {
  115. case _T('r'):
  116. #ifdef _POSIX_
  117. modeflag = O_RDONLY;
  118. #else
  119. modeflag = _O_RDONLY;
  120. #endif
  121. streamflag |= _IOREAD;
  122. break;
  123. case _T('w'):
  124. #ifdef _POSIX_
  125. modeflag = O_WRONLY | O_CREAT | O_TRUNC;
  126. #else
  127. modeflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
  128. #endif
  129. streamflag |= _IOWRT;
  130. break;
  131. case _T('a'):
  132. #ifdef _POSIX_
  133. modeflag = O_WRONLY | O_CREAT | O_APPEND;
  134. streamflag |= _IOWRT | _IOAPPEND;
  135. #else
  136. modeflag = _O_WRONLY | _O_CREAT | _O_APPEND;
  137. streamflag |= _IOWRT;
  138. #endif
  139. break;
  140. default:
  141. return(NULL);
  142. break;
  143. }
  144. /* There can be up to three more optional mode characters:
  145. (1) A single '+' character,
  146. (2) One of 't' and 'b' and
  147. (3) One of 'c' and 'n'.
  148. */
  149. whileflag=1;
  150. while(*++mode && whileflag)
  151. switch(*mode) {
  152. case _T('+'):
  153. #ifdef _POSIX_
  154. if (modeflag & O_RDWR)
  155. whileflag=0;
  156. else {
  157. modeflag |= O_RDWR;
  158. modeflag &= ~(O_RDONLY | O_WRONLY);
  159. #else
  160. if (modeflag & _O_RDWR)
  161. whileflag=0;
  162. else {
  163. modeflag |= _O_RDWR;
  164. modeflag &= ~(_O_RDONLY | _O_WRONLY);
  165. #endif
  166. streamflag |= _IORW;
  167. streamflag &= ~(_IOREAD | _IOWRT);
  168. }
  169. break;
  170. case _T('b'):
  171. #ifndef _POSIX_
  172. if (modeflag & (_O_TEXT | _O_BINARY))
  173. whileflag=0;
  174. else
  175. modeflag |= _O_BINARY;
  176. #endif
  177. break;
  178. #ifndef _POSIX_
  179. case _T('t'):
  180. if (modeflag & (_O_TEXT | _O_BINARY))
  181. whileflag=0;
  182. else
  183. modeflag |= _O_TEXT;
  184. break;
  185. case _T('c'):
  186. if (commodeset)
  187. whileflag=0;
  188. else {
  189. commodeset = 1;
  190. streamflag |= _IOCOMMIT;
  191. }
  192. break;
  193. case _T('n'):
  194. if (commodeset)
  195. whileflag=0;
  196. else {
  197. commodeset = 1;
  198. streamflag &= ~_IOCOMMIT;
  199. }
  200. break;
  201. case _T('S'):
  202. if (scanset)
  203. whileflag=0;
  204. else {
  205. scanset = 1;
  206. modeflag |= _O_SEQUENTIAL;
  207. }
  208. break;
  209. case _T('R'):
  210. if (scanset)
  211. whileflag=0;
  212. else {
  213. scanset = 1;
  214. modeflag |= _O_RANDOM;
  215. }
  216. break;
  217. case _T('T'):
  218. if (modeflag & _O_SHORT_LIVED)
  219. whileflag=0;
  220. else
  221. modeflag |= _O_SHORT_LIVED;
  222. break;
  223. case _T('D'):
  224. if (modeflag & _O_TEMPORARY)
  225. whileflag=0;
  226. else
  227. modeflag |= _O_TEMPORARY;
  228. break;
  229. #endif
  230. default:
  231. whileflag=0;
  232. break;
  233. }
  234. /* Try to open the file. Note that if neither 't' nor 'b' is
  235. specified, _sopen will use the default. */
  236. #ifdef _POSIX_
  237. if ((filedes = _topen(filename, modeflag, P_CMASK)) < 0)
  238. #else
  239. if ((filedes = _tsopen(filename, modeflag, shflag, CMASK)) < 0)
  240. #endif
  241. return(NULL);
  242. /* Set up the stream data base. */
  243. #ifndef CRTDLL
  244. _cflush++; /* force library pre-termination procedure */
  245. #endif /* CRTDLL */
  246. /* Init pointers */
  247. stream = str;
  248. stream->_flag = streamflag;
  249. stream->_cnt = 0;
  250. stream->_tmpfname = stream->_base = stream->_ptr = NULL;
  251. stream->_file = filedes;
  252. return(stream);
  253. }