ReactOS  0.4.14-dev-342-gdc047f9
fstream_unistd.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1999
3  * Silicon Graphics Computer Systems, Inc.
4  *
5  * Copyright (c) 1999
6  * Boris Fomitchev
7  *
8  * This material is provided "as is", with absolutely no warranty expressed
9  * or implied. Any use is at your own risk.
10  *
11  * Permission to use or copy this software for any purpose is hereby granted
12  * without fee, provided the above notices are retained on all copies.
13  * Permission to modify the code and to distribute modified code is granted,
14  * provided the above notices are retained, and a notice that the code was
15  * modified is included with the above copyright notice.
16  *
17  */
18 
19 #if defined (__SUNPPRO_CC) && !defined (_STLP_NO_NEW_C_HEADERS)
20 # include <time.h>
21 // For sunpro, it chokes if time.h is included through stat.h
22 #endif
23 
24 #include <fstream>
25 
26 #ifdef __CYGWIN__
27 # define __int64 long long
28 #endif
29 
30 extern "C" {
31 // open/close/read/write
32 #include <sys/stat.h> // For stat
33 #if !defined (_CRAY) && ! defined (__EMX__)
34 # include <sys/mman.h> // For mmap
35 #endif
36 
37 // on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this
38 #if defined (__hpux) && defined (__GNUC__)
39 # undef _INCLUDE_POSIX1C_SOURCE
40 #endif
41 
42 #include <unistd.h>
43 #include <fcntl.h>
44 }
45 
46 #ifdef __APPLE__
47 # include <sys/sysctl.h>
48 #endif
49 
50 const _STLP_fd INVALID_STLP_FD = -1;
51 
52 #ifndef O_ACCMODE
53 # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
54 #endif
55 
56 // Compare with streamoff definition in stl/char_traits.h!
57 #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \
58  (!defined(_LARGEFILE_SOURCE) && !defined (_LARGEFILE64_SOURCE))
59 # define FSTAT fstat
60 # define STAT stat
61 # define LSEEK lseek
62 # define MMAP mmap
63 # define OPEN open
64 #else
65 # define FSTAT fstat64
66 # define STAT stat64
67 # define LSEEK lseek64
68 # define MMAP mmap64
69 # define OPEN open64
70 #endif
71 
72 #ifndef MAP_FAILED /* MMAP failure return code */
73 # define MAP_FAILED -1
74 #endif
75 
77 
79 {
80  ios_base::openmode ret = ios_base::__default_mode;
81 
82  switch ( mode & O_ACCMODE ) {
83  case O_RDONLY:
84  ret = ios_base::in;
85  break;
86  case O_WRONLY:
88  break;
89  case O_RDWR:
91  break;
92  }
93 
94  if ( mode & O_APPEND )
95  ret |= ios_base::app;
96 
97  return ret;
98 }
99 
101 
102 // Helper functions for _Filebuf_base.
103 
104 static bool __is_regular_file(_STLP_fd fd) {
105  struct STAT buf;
106  return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode);
107 }
108 
109 // Number of characters in the file.
110 static streamoff __file_size(_STLP_fd fd) {
111  streamoff ret = 0;
112 
113  struct STAT buf;
114  if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode))
115  ret = buf.st_size > 0 ? buf.st_size : 0;
116 
117  return ret;
118 }
119 
121 
122 size_t _Filebuf_base::_M_page_size = 4096;
123 
125  : _M_file_id(INVALID_STLP_FD),
126  _M_openmode(0),
127  _M_is_open(false),
128  _M_should_close(false)
129 {}
130 
132 {
133 #if defined (__APPLE__)
134  int mib[2];
135  size_t pagesize, len;
136  mib[0] = CTL_HW;
137  mib[1] = HW_PAGESIZE;
138  len = sizeof(pagesize);
139  sysctl(mib, 2, &pagesize, &len, NULL, 0);
140  _M_page_size = pagesize;
141 #elif defined (__DJGPP) && defined (_CRAY)
143 #else
144  _M_page_size = sysconf(_SC_PAGESIZE);
145 #endif
146 }
147 
148 // Return the size of the file. This is a wrapper for stat.
149 // Returns zero if the size cannot be determined or is ill-defined.
151 {
153 }
154 
155 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,
156  long permission)
157 {
158  _STLP_fd file_no;
159 
160  if (_M_is_open)
161  return false;
162 
163  int flags = 0;
164 
165  // Unix makes no distinction between text and binary files.
166  switch ( openmode & (~ios_base::ate & ~ios_base::binary) ) {
167  case ios_base::out:
170  break;
171  case ios_base::app:
172  case ios_base::out | ios_base::app:
174  break;
175  case ios_base::in:
176  flags = O_RDONLY;
177  permission = 0; // Irrelevant unless we're writing.
178  break;
180  flags = O_RDWR;
181  break;
183  flags = O_RDWR | O_CREAT | O_TRUNC;
184  break;
185  case ios_base::in | ios_base::app:
186  case ios_base::in | ios_base::out | ios_base::app:
188  break;
189  default: // The above are the only combinations of
190  return false; // flags allowed by the C++ standard.
191  }
192 
193  file_no = OPEN(name, flags, permission);
194 
195  if (file_no < 0)
196  return false;
197 
198  _M_is_open = true;
199 
200  if ((openmode & (ios_base::ate | ios_base::app)) && (LSEEK(file_no, 0, SEEK_END) == -1)) {
201  _M_is_open = false;
202  }
203 
204  _M_file_id = file_no;
206  _M_openmode = openmode;
207 
208  if (_M_is_open)
210 
211  return (_M_is_open != 0);
212 }
213 
214 
215 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode)
216 {
217  // This doesn't really grant everyone in the world read/write
218  // access. On Unix, file-creation system calls always clear
219  // bits that are set in the umask from the permissions flag.
220  return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP |
221  S_IWGRP | S_IROTH | S_IWOTH);
222 }
223 
224 // Associated the filebuf with a file descriptor pointing to an already-
225 // open file. Mode is set to be consistent with the way that the file
226 // was opened.
228 {
229  if (_M_is_open || file_no < 0)
230  return false;
231 
232  int mode = fcntl(file_no, F_GETFL);
233 
234  if (mode == -1)
235  return false;
236 
238  _M_file_id = file_no;
239 
240  _M_is_open = true;
241  _M_should_close = false;
243  return true;
244 }
245 
247 {
248  if (!_M_is_open)
249  return false;
250 
251  bool ok = _M_should_close ? (close(_M_file_id) == 0) : true;
252 
253  _M_is_open = _M_should_close = false;
254  _M_openmode = 0;
255  return ok;
256 }
257 
258 // Read up to n characters into a buffer. Return value is number of
259 // characters read.
261 {
262  return read(_M_file_id, buf, n);
263 }
264 
265 // Write n characters from a buffer. Return value: true if we managed
266 // to write the entire buffer, false if we didn't.
268 {
269  for (;;) {
270  ptrdiff_t written = write(_M_file_id, buf, n);
271 
272  if (n == written) {
273  return true;
274  }
275 
276  if (written > 0 && written < n) {
277  n -= written;
278  buf += written;
279  } else {
280  return false;
281  }
282  }
283 }
284 
285 // Wrapper for lseek or the like.
287 {
288  int whence;
289 
290  switch ( dir ) {
291  case ios_base::beg:
293  return streamoff(-1);
294  whence = SEEK_SET;
295  break;
296  case ios_base::cur:
297  whence = SEEK_CUR;
298  break;
299  case ios_base::end:
300  if (/* offset > 0 || */ -offset > _M_file_size() )
301  return streamoff(-1);
302  whence = SEEK_END;
303  break;
304  default:
305  return streamoff(-1);
306  }
307 
308  return LSEEK(_M_file_id, offset, whence);
309 }
310 
311 // Attempts to memory-map len bytes of the current file, starting
312 // at position offset. Precondition: offset is a multiple of the
313 // page size. Postcondition: return value is a null pointer if the
314 // memory mapping failed. Otherwise the return value is a pointer to
315 // the memory-mapped file and the file position is set to offset.
317 {
318  void* base;
319 #if !defined (__DJGPP) && !defined (_CRAY)
320  base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset);
321  if (base != (void*)MAP_FAILED) {
322  if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) {
323  this->_M_unmap(base, len);
324  base = 0;
325  }
326  } else
327  base =0;
328 #else
331  base = 0;
332 #endif
333  return base;
334 }
335 
337 {
338  // precondition : there is a valid mapping at the moment
339 #if !defined (__DJGPP) && !defined (_CRAY)
340  munmap((char*)base, len);
341 #else
344 #endif
345 }
346 
off_t streamoff
Definition: char_traits.h:74
#define SEEK_CUR
Definition: util.h:63
#define LSEEK
static size_t _M_page_size
Definition: _fstream.h:113
unsigned char _M_regular_file
Definition: _fstream.h:124
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define O_ACCMODE
GLintptr offset
Definition: glext.h:5920
ptrdiff_t _M_read(char *__buf, ptrdiff_t __n)
GLdouble n
Definition: glext.h:7729
static int fd
Definition: io.c:51
#define BUFSIZ
Definition: nsplookup.c:26
GLuint GLuint end
Definition: gl.h:1545
int seekdir
Definition: _ios_base.h:60
unsigned char _M_should_close
Definition: _fstream.h:123
#define _STLP_MOVE_TO_PRIV_NAMESPACE
Definition: features.h:524
void _M_unmap(void *__mmap_base, streamoff __len)
#define write
Definition: acwin.h:97
static void _S_initialize()
GLuint base
Definition: 3dtext.c:35
#define S_IRGRP
Definition: propsheet.h:41
#define O_WRONLY
Definition: acwin.h:111
double __cdecl trunc(double)
ios_base::openmode _M_openmode
Definition: _fstream.h:121
streamoff _M_file_size()
smooth NULL
Definition: ftsmooth.c:416
unsigned int dir
Definition: maze.c:112
#define OPEN
#define SEEK_SET
Definition: jmemansi.c:26
#define S_IWGRP
Definition: propsheet.h:45
#define _STLP_MOVE_TO_STD_NAMESPACE
Definition: features.h:525
#define S_IWUSR
Definition: propsheet.h:33
static _STLP_MOVE_TO_PRIV_NAMESPACE bool __is_regular_file(_STLP_fd fd)
int openmode
Definition: _ios_base.h:59
void * _M_mmap(streamoff __offset, streamoff __len)
#define _STLP_MARK_PARAMETER_AS_UNUSED(X)
Definition: _dm.h:68
static FILE * out
Definition: regtests2xml.c:44
const GLuint GLenum const GLvoid * binary
Definition: glext.h:7538
#define MAP_FAILED
GLbitfield flags
Definition: glext.h:7161
int ret
streamoff _M_seek(streamoff __offset, ios_base::seekdir __dir)
#define S_IROTH
Definition: propsheet.h:53
#define _STLP_PRIV
Definition: _dm.h:70
GLenum GLsizei len
Definition: glext.h:6722
#define false
Definition: stdbool.h:38
#define O_TRUNC
Definition: acwin.h:112
unsigned char _M_is_open
Definition: _fstream.h:122
#define close
Definition: acwin.h:98
GLenum mode
Definition: glext.h:6217
#define S_IWOTH
Definition: propsheet.h:57
bool _M_write(char *__buf, ptrdiff_t __n)
GLuint in
Definition: glext.h:9616
#define O_RDWR
Definition: fcntl.h:36
#define ok(value,...)
Definition: atltest.h:57
#define STAT
#define _STLP_END_NAMESPACE
Definition: features.h:503
#define S_IRUSR
Definition: propsheet.h:29
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
bool _M_open(const char *, ios_base::openmode, long __protection)
const _STLP_fd INVALID_STLP_FD
#define MMAP
Definition: name.c:36
static _STLP_BEGIN_NAMESPACE ios_base::openmode flag_to_openmode(int mode)
_STLP_fd _M_file_id
Definition: _fstream.h:116
#define SEEK_END
Definition: cabinet.c:27
static streamoff __file_size(_STLP_fd fd)
#define FSTAT
#define _STLP_BEGIN_NAMESPACE
Definition: features.h:501
#define S_ISREG(mode)
Definition: various.h:17
#define O_CREAT
Definition: acwin.h:110
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define O_APPEND
Definition: fcntl.h:37
#define O_RDONLY
Definition: acwin.h:108