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.

233 lines
5.0 KiB

  1. /***
  2. *filebuf1.cpp - non-core filebuf member functions.
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Contains optional member functions for filebuf class.
  8. *
  9. *Revision History:
  10. * 09-21-91 KRS Created. Split off from fstream.cxx.
  11. * 10-24-91 KRS C700 #4909: Typo/logic bug in setmode().
  12. * 11-06-91 KRS Add support for share mode in open(). Use _sopen().
  13. * 08-19-92 KRS Use _SH_DENYNO for default mode for NT.
  14. * 03-02-93 SKS Avoid setting _O_TRUNC when noreplace is specified
  15. * 01-12-95 CFW Debug CRT allocs.
  16. * 06-14-95 CFW Comment cleanup.
  17. *
  18. *******************************************************************************/
  19. #include <cruntime.h>
  20. #include <internal.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <fcntl.h>
  25. #include <share.h>
  26. #include <sys\types.h>
  27. #include <io.h>
  28. #include <fstream.h>
  29. #include <dbgint.h>
  30. #pragma hdrstop
  31. #include <sys\stat.h>
  32. /***
  33. *filebuf* filebuf::attach(filedesc fd) - filebuf attach function
  34. *
  35. *Purpose:
  36. * filebuf attach() member function. Attach filebuf object to the
  37. * given file descriptor previously obtained from _open() or _sopen().
  38. *
  39. *Entry:
  40. * fd = file descriptor.
  41. *
  42. *Exit:
  43. * Returns this pointer or NULL if error.
  44. *
  45. *Exceptions:
  46. * Returns NULL if fd = -1.
  47. *
  48. *******************************************************************************/
  49. filebuf* filebuf::attach(filedesc fd)
  50. {
  51. if (x_fd!=-1)
  52. return NULL; // error if already attached
  53. lock();
  54. x_fd = fd;
  55. if ((fd!=-1) && (!unbuffered()) && (!ebuf()))
  56. {
  57. char * sbuf = _new_crt char[BUFSIZ];
  58. if (!sbuf)
  59. {
  60. unbuffered(1);
  61. }
  62. else
  63. {
  64. streambuf::setb(sbuf,sbuf+BUFSIZ,1);
  65. }
  66. }
  67. unlock();
  68. return this;
  69. }
  70. /***
  71. *filebuf* filebuf::open(const char* name, int mode, int share) - filebuf open
  72. *
  73. *Purpose:
  74. * filebuf open() member function. Open a file and attach to filebuf
  75. * object.
  76. *
  77. *Entry:
  78. * name = file name string.
  79. * mode = open mode: Combination of ios:: in, out, binary, nocreate, app,
  80. * ate, noreplace and trunc. See spec. for details on behavior.
  81. * share = share mode (optional). sh_compat, sh_none, sh_read, sh_write.
  82. *
  83. *Exit:
  84. * Returns this pointer or NULL if error.
  85. *
  86. *Exceptions:
  87. * Returns NULL if filebuf is already attached to an open file, or if
  88. * invalid mode options, or if call to _sopen or filebuf::seekoff() fails.
  89. *
  90. *******************************************************************************/
  91. filebuf* filebuf::open(const char* name, int mode, int share)
  92. {
  93. int dos_mode;
  94. int smode;
  95. if (x_fd!=-1)
  96. return NULL; // error if already open
  97. // translate mode argument
  98. dos_mode = (mode & ios::binary) ? O_BINARY : O_TEXT;
  99. if (!(mode & ios::nocreate))
  100. dos_mode |= O_CREAT;
  101. if (mode & ios::noreplace)
  102. dos_mode |= O_EXCL;
  103. if (mode & ios::app)
  104. {
  105. mode |= ios::out;
  106. dos_mode |= O_APPEND;
  107. }
  108. if (mode & ios::trunc)
  109. {
  110. mode |= ios::out; // IMPLIED
  111. dos_mode |= O_TRUNC;
  112. }
  113. if (mode & ios::out)
  114. {
  115. if (mode & ios::in)
  116. {
  117. dos_mode |= O_RDWR;
  118. }
  119. else
  120. {
  121. dos_mode |= O_WRONLY;
  122. }
  123. if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace)))
  124. {
  125. mode |= ios::trunc; // IMPLIED
  126. dos_mode |= O_TRUNC;
  127. }
  128. }
  129. else if (mode & ios::in)
  130. dos_mode |= O_RDONLY;
  131. else
  132. return NULL; // error if not ios:in or ios::out
  133. smode = _SH_DENYNO; // default for NT
  134. share &= (sh_read|sh_write|sh_none); // ignore other bits
  135. if (share) // optimization openprot serves as default
  136. {
  137. switch (share)
  138. {
  139. /* case 03000 : Reserved for sh_compat */
  140. // case sh_none :
  141. case 04000 :
  142. smode = _SH_DENYRW;
  143. break;
  144. // case sh_read :
  145. case 05000 :
  146. smode = _SH_DENYWR;
  147. break;
  148. // case sh_write :
  149. case 06000 :
  150. smode = _SH_DENYRD;
  151. break;
  152. // case (sh_read|sh_write) :
  153. case 07000 :
  154. smode = _SH_DENYNO;
  155. break;
  156. default : // unrecognized value same as default
  157. break;
  158. };
  159. }
  160. x_fd = _sopen(name, dos_mode, smode, S_IREAD|S_IWRITE);
  161. if (x_fd==-1)
  162. return NULL;
  163. lock();
  164. x_fOpened = 1;
  165. if ((!unbuffered()) && (!ebuf()))
  166. {
  167. char * sbuf = _new_crt char[BUFSIZ];
  168. if (!sbuf)
  169. {
  170. unbuffered(1);
  171. }
  172. else
  173. {
  174. streambuf::setb(sbuf,sbuf+BUFSIZ,1);
  175. }
  176. }
  177. if (mode & ios::ate)
  178. if (seekoff(0,ios::end,mode)==EOF)
  179. {
  180. close();
  181. unlock();
  182. return NULL;
  183. }
  184. unlock();
  185. return this;
  186. }
  187. /***
  188. *int filebuf::setmode(int mode) - filebuf setmode function
  189. *
  190. *Purpose:
  191. * filebuf setmode() member function. Set binary or text access mode.
  192. * Calls _setmode().
  193. *
  194. * MS-specific extension.
  195. *
  196. *Entry:
  197. * mode = filebuf::binary or filebuf::text.
  198. *
  199. *Exit:
  200. * Returns previous mode, or -1 error.
  201. *
  202. *Exceptions:
  203. * Return -1 (EOF) if invalid argument or _setmode fails.
  204. *
  205. *******************************************************************************/
  206. int filebuf::setmode(int mode)
  207. {
  208. int retval;
  209. if ((mode!=filebuf::binary) && (mode!=filebuf::text))
  210. return -1;
  211. lock();
  212. if ((x_fd==-1) || (sync()==EOF))
  213. {
  214. retval = -1;
  215. }
  216. else
  217. {
  218. retval = _setmode(x_fd,mode);
  219. }
  220. unlock();
  221. return retval;
  222. }