build/stlport/src/details/fstream_stdio.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright (c) 1999
michael@0 3 * Silicon Graphics Computer Systems, Inc.
michael@0 4 *
michael@0 5 * Copyright (c) 1999
michael@0 6 * Boris Fomitchev
michael@0 7 *
michael@0 8 * This material is provided "as is", with absolutely no warranty expressed
michael@0 9 * or implied. Any use is at your own risk.
michael@0 10 *
michael@0 11 * Permission to use or copy this software for any purpose is hereby granted
michael@0 12 * without fee, provided the above notices are retained on all copies.
michael@0 13 * Permission to modify the code and to distribute modified code is granted,
michael@0 14 * provided the above notices are retained, and a notice that the code was
michael@0 15 * modified is included with the above copyright notice.
michael@0 16 *
michael@0 17 */
michael@0 18
michael@0 19 #if defined (__SUNPPRO_CC) && !defined (_STLP_NO_NEW_C_HEADERS)
michael@0 20 # include <time.h>
michael@0 21 // For sunpro, it chokes if time.h is included through stat.h
michael@0 22 #endif
michael@0 23
michael@0 24 #include <fstream>
michael@0 25
michael@0 26 #ifdef __CYGWIN__
michael@0 27 # define __int64 long long
michael@0 28 #endif
michael@0 29
michael@0 30 #include <cstdio>
michael@0 31 #if !defined(__ISCPP__)
michael@0 32 extern "C" {
michael@0 33 # include <sys/stat.h>
michael@0 34 }
michael@0 35 #endif
michael@0 36
michael@0 37 #if defined( __MSL__ )
michael@0 38 # include <unix.h>
michael@0 39 #endif
michael@0 40
michael@0 41 #if defined(__ISCPP__)
michael@0 42 # include <c_locale_is/filestat.h>
michael@0 43 #endif
michael@0 44
michael@0 45 #if defined(__BEOS__) && defined(__INTEL__)
michael@0 46 # include <fcntl.h>
michael@0 47 # include <sys/stat.h> // For _fstat
michael@0 48 #endif
michael@0 49
michael@0 50 #if defined (_STLP_MSVC) || defined (__MINGW32__)
michael@0 51 # include <fcntl.h>
michael@0 52 # define S_IREAD _S_IREAD
michael@0 53 # define S_IWRITE _S_IWRITE
michael@0 54 # define S_IFREG _S_IFREG
michael@0 55 // map permission masks
michael@0 56 # ifndef S_IRUSR
michael@0 57 # define S_IRUSR _S_IREAD
michael@0 58 # define S_IWUSR _S_IWRITE
michael@0 59 # endif
michael@0 60 # ifndef S_IRGRP
michael@0 61 # define S_IRGRP _S_IREAD
michael@0 62 # define S_IWGRP _S_IWRITE
michael@0 63 # endif
michael@0 64 # ifndef S_IROTH
michael@0 65 # define S_IROTH _S_IREAD
michael@0 66 # define S_IWOTH _S_IWRITE
michael@0 67 # endif
michael@0 68
michael@0 69 # ifndef O_RDONLY
michael@0 70 # define O_RDONLY _O_RDONLY
michael@0 71 # define O_WRONLY _O_WRONLY
michael@0 72 # define O_RDWR _O_RDWR
michael@0 73 # define O_APPEND _O_APPEND
michael@0 74 # define O_CREAT _O_CREAT
michael@0 75 # define O_TRUNC _O_TRUNC
michael@0 76 # define O_TEXT _O_TEXT
michael@0 77 # define O_BINARY _O_BINARY
michael@0 78 # endif
michael@0 79
michael@0 80 # ifndef O_ACCMODE
michael@0 81 # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
michael@0 82 # endif
michael@0 83 #endif
michael@0 84
michael@0 85 const _STLP_fd INVALID_STLP_FD = -1;
michael@0 86
michael@0 87
michael@0 88 # ifdef __MSL__
michael@0 89 # define _O_TEXT 0x0
michael@0 90 # if !defined( O_TEXT )
michael@0 91 # define O_TEXT _O_TEXT
michael@0 92 # endif
michael@0 93 # define _S_IFREG S_IFREG
michael@0 94 # define S_IREAD S_IRUSR
michael@0 95 # define S_IWRITE S_IWUSR
michael@0 96 # define S_IEXEC S_IXUSR
michael@0 97 # define _S_IWRITE S_IWRITE
michael@0 98 # define _S_IREAD S_IREAD
michael@0 99 # define _open open
michael@0 100 # define _close close
michael@0 101 # define _read read
michael@0 102 # define _write write
michael@0 103 # endif
michael@0 104
michael@0 105 _STLP_BEGIN_NAMESPACE
michael@0 106
michael@0 107 // Compare with streamoff definition in stl/char_traits.h!
michael@0 108
michael@0 109 #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \
michael@0 110 (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE))
michael@0 111 # define FOPEN fopen
michael@0 112 # define FSEEK fseek
michael@0 113 # define FSTAT fstat
michael@0 114 # define STAT stat
michael@0 115 # define FTELL ftell
michael@0 116 #else
michael@0 117 # define FOPEN fopen64
michael@0 118 # define FSEEK fseeko64
michael@0 119 # define FSTAT fstat64
michael@0 120 # define STAT stat64
michael@0 121 # define FTELL ftello64
michael@0 122 #endif
michael@0 123
michael@0 124 _STLP_MOVE_TO_PRIV_NAMESPACE
michael@0 125
michael@0 126 // Helper functions for _Filebuf_base.
michael@0 127
michael@0 128 static bool __is_regular_file(_STLP_fd fd) {
michael@0 129 struct STAT buf;
michael@0 130 return FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0 ;
michael@0 131 }
michael@0 132
michael@0 133 // Number of characters in the file.
michael@0 134 static streamoff __file_size(_STLP_fd fd) {
michael@0 135 streamoff ret = 0;
michael@0 136
michael@0 137 struct STAT buf;
michael@0 138 if (FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0)
michael@0 139 ret = buf.st_size > 0 ? buf.st_size : 0;
michael@0 140
michael@0 141 return ret;
michael@0 142 }
michael@0 143
michael@0 144 _STLP_MOVE_TO_STD_NAMESPACE
michael@0 145
michael@0 146 // All version of Unix have mmap and lseek system calls. Some also have
michael@0 147 // longer versions of those system calls to accommodate 64-bit offsets.
michael@0 148 // If we're on a Unix system, define some macros to encapsulate those
michael@0 149 // differences.
michael@0 150
michael@0 151 size_t _Filebuf_base::_M_page_size = 4096;
michael@0 152
michael@0 153 _Filebuf_base::_Filebuf_base()
michael@0 154 : _M_file_id(INVALID_STLP_FD),
michael@0 155 _M_openmode(0),
michael@0 156 _M_is_open(false),
michael@0 157 _M_should_close(false)
michael@0 158 {}
michael@0 159
michael@0 160 void _Filebuf_base::_S_initialize()
michael@0 161 {
michael@0 162
michael@0 163 }
michael@0 164
michael@0 165 // Return the size of the file. This is a wrapper for stat.
michael@0 166 // Returns zero if the size cannot be determined or is ill-defined.
michael@0 167 streamoff _Filebuf_base::_M_file_size()
michael@0 168 {
michael@0 169 return _STLP_PRIV __file_size(_M_file_id);
michael@0 170 }
michael@0 171
michael@0 172 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,
michael@0 173 long permission)
michael@0 174 {
michael@0 175 _STLP_fd file_no;
michael@0 176
michael@0 177 if (_M_is_open)
michael@0 178 return false;
michael@0 179
michael@0 180 // use FILE-based i/o
michael@0 181 const char* flags;
michael@0 182
michael@0 183 switch (openmode & (~ios_base::ate)) {
michael@0 184 case ios_base::out:
michael@0 185 case ios_base::out | ios_base::trunc:
michael@0 186 flags = "w";
michael@0 187 break;
michael@0 188
michael@0 189 case ios_base::out | ios_base::binary:
michael@0 190 case ios_base::out | ios_base::trunc | ios_base::binary:
michael@0 191 flags = "wb";
michael@0 192 break;
michael@0 193
michael@0 194 case ios_base::out | ios_base::app:
michael@0 195 flags = "a";
michael@0 196 break;
michael@0 197
michael@0 198 case ios_base::out | ios_base::app | ios_base::binary:
michael@0 199 flags = "ab";
michael@0 200 break;
michael@0 201
michael@0 202 case ios_base::in:
michael@0 203 flags = "r";
michael@0 204 break;
michael@0 205
michael@0 206 case ios_base::in | ios_base::binary:
michael@0 207 flags = "rb";
michael@0 208 break;
michael@0 209
michael@0 210 case ios_base::in | ios_base::out:
michael@0 211 flags = "r+";
michael@0 212 break;
michael@0 213
michael@0 214 case ios_base::in | ios_base::out | ios_base::binary:
michael@0 215 flags = "r+b";
michael@0 216 break;
michael@0 217
michael@0 218 case ios_base::in | ios_base::out | ios_base::trunc:
michael@0 219 flags = "w+";
michael@0 220 break;
michael@0 221
michael@0 222 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
michael@0 223 flags = "w+b";
michael@0 224 break;
michael@0 225
michael@0 226 default: // The above are the only combinations of
michael@0 227 return false; // flags allowed by the C++ standard.
michael@0 228 }
michael@0 229
michael@0 230 // fbp : TODO : set permissions !
michael@0 231 (void)permission; // currently unused //*TY 02/26/2000 - added to suppress warning message
michael@0 232 _M_file = FOPEN(name, flags);
michael@0 233
michael@0 234 if (_M_file) {
michael@0 235 file_no = fileno(_M_file);
michael@0 236 } else {
michael@0 237 return false;
michael@0 238 }
michael@0 239
michael@0 240 // unset buffering immediately
michael@0 241 setbuf(_M_file, 0);
michael@0 242
michael@0 243 _M_is_open = true;
michael@0 244
michael@0 245 if (openmode & ios_base::ate) {
michael@0 246 if (FSEEK(_M_file, 0, SEEK_END) != 0)
michael@0 247 _M_is_open = false;
michael@0 248 }
michael@0 249
michael@0 250 _M_file_id = file_no;
michael@0 251 _M_should_close = _M_is_open;
michael@0 252 _M_openmode = openmode;
michael@0 253
michael@0 254 if (_M_is_open)
michael@0 255 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
michael@0 256
michael@0 257 return (_M_is_open != 0);
michael@0 258 }
michael@0 259
michael@0 260
michael@0 261 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode)
michael@0 262 {
michael@0 263 // This doesn't really grant everyone in the world read/write
michael@0 264 // access. On Unix, file-creation system calls always clear
michael@0 265 // bits that are set in the umask from the permissions flag.
michael@0 266 return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP |
michael@0 267 S_IWGRP | S_IROTH | S_IWOTH);
michael@0 268 }
michael@0 269
michael@0 270 // Associated the filebuf with a file descriptor pointing to an already-
michael@0 271 // open file. Mode is set to be consistent with the way that the file
michael@0 272 // was opened.
michael@0 273 bool _Filebuf_base::_M_open( int file_no, ios_base::openmode )
michael@0 274 {
michael@0 275 if (_M_is_open || file_no < 0)
michael@0 276 return false;
michael@0 277
michael@0 278 struct STAT buf;
michael@0 279 if (FSTAT(file_no, &buf) != 0)
michael@0 280 return false;
michael@0 281 int mode = buf.st_mode;
michael@0 282
michael@0 283 switch ( mode & (S_IWRITE | S_IREAD) ) {
michael@0 284 case S_IREAD:
michael@0 285 _M_openmode = ios_base::in;
michael@0 286 break;
michael@0 287 case S_IWRITE:
michael@0 288 _M_openmode = ios_base::out;
michael@0 289 break;
michael@0 290 case (S_IWRITE | S_IREAD):
michael@0 291 _M_openmode = ios_base::in | ios_base::out;
michael@0 292 break;
michael@0 293 default:
michael@0 294 return false;
michael@0 295 }
michael@0 296 _M_file_id = file_no;
michael@0 297 _M_is_open = true;
michael@0 298 _M_should_close = false;
michael@0 299 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
michael@0 300 return true;
michael@0 301 }
michael@0 302
michael@0 303 bool _Filebuf_base::_M_close()
michael@0 304 {
michael@0 305 if (!_M_is_open)
michael@0 306 return false;
michael@0 307
michael@0 308 bool ok = _M_should_close ? (fclose(_M_file) == 0) : true;
michael@0 309
michael@0 310 _M_is_open = _M_should_close = false;
michael@0 311 _M_openmode = 0;
michael@0 312 return ok;
michael@0 313 }
michael@0 314
michael@0 315 // Read up to n characters into a buffer. Return value is number of
michael@0 316 // characters read.
michael@0 317 ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) {
michael@0 318 return fread(buf, 1, n, _M_file);
michael@0 319 }
michael@0 320
michael@0 321 // Write n characters from a buffer. Return value: true if we managed
michael@0 322 // to write the entire buffer, false if we didn't.
michael@0 323 bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n)
michael@0 324 {
michael@0 325 for (;;) {
michael@0 326 ptrdiff_t written = fwrite(buf, 1, n, _M_file);
michael@0 327
michael@0 328 if (n == written) {
michael@0 329 return true;
michael@0 330 }
michael@0 331
michael@0 332 if (written > 0 && written < n) {
michael@0 333 n -= written;
michael@0 334 buf += written;
michael@0 335 } else {
michael@0 336 return false;
michael@0 337 }
michael@0 338 }
michael@0 339 }
michael@0 340
michael@0 341 // Wrapper for lseek or the like.
michael@0 342 streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir)
michael@0 343 {
michael@0 344 int whence;
michael@0 345
michael@0 346 switch ( dir ) {
michael@0 347 case ios_base::beg:
michael@0 348 if (offset < 0 /* || offset > _M_file_size() */ )
michael@0 349 return streamoff(-1);
michael@0 350 whence = SEEK_SET;
michael@0 351 break;
michael@0 352 case ios_base::cur:
michael@0 353 whence = SEEK_CUR;
michael@0 354 break;
michael@0 355 case ios_base::end:
michael@0 356 if (/* offset > 0 || */ -offset > _M_file_size() )
michael@0 357 return streamoff(-1);
michael@0 358 whence = SEEK_END;
michael@0 359 break;
michael@0 360 default:
michael@0 361 return streamoff(-1);
michael@0 362 }
michael@0 363
michael@0 364 if ( FSEEK(_M_file, offset, whence) == 0 ) {
michael@0 365 return FTELL(_M_file);
michael@0 366 }
michael@0 367
michael@0 368 return streamoff(-1);
michael@0 369 }
michael@0 370
michael@0 371
michael@0 372 // Attempts to memory-map len bytes of the current file, starting
michael@0 373 // at position offset. Precondition: offset is a multiple of the
michael@0 374 // page size. Postcondition: return value is a null pointer if the
michael@0 375 // memory mapping failed. Otherwise the return value is a pointer to
michael@0 376 // the memory-mapped file and the file position is set to offset.
michael@0 377 void *_Filebuf_base::_M_mmap(streamoff, streamoff )
michael@0 378 {
michael@0 379 return 0;
michael@0 380 }
michael@0 381
michael@0 382 void _Filebuf_base::_M_unmap(void*, streamoff)
michael@0 383 {
michael@0 384 // precondition : there is a valid mapping at the moment
michael@0 385 }
michael@0 386
michael@0 387 _STLP_END_NAMESPACE

mercurial