1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/stlport/src/details/fstream_stdio.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,387 @@ 1.4 +/* 1.5 + * Copyright (c) 1999 1.6 + * Silicon Graphics Computer Systems, Inc. 1.7 + * 1.8 + * Copyright (c) 1999 1.9 + * Boris Fomitchev 1.10 + * 1.11 + * This material is provided "as is", with absolutely no warranty expressed 1.12 + * or implied. Any use is at your own risk. 1.13 + * 1.14 + * Permission to use or copy this software for any purpose is hereby granted 1.15 + * without fee, provided the above notices are retained on all copies. 1.16 + * Permission to modify the code and to distribute modified code is granted, 1.17 + * provided the above notices are retained, and a notice that the code was 1.18 + * modified is included with the above copyright notice. 1.19 + * 1.20 + */ 1.21 + 1.22 +#if defined (__SUNPPRO_CC) && !defined (_STLP_NO_NEW_C_HEADERS) 1.23 +# include <time.h> 1.24 +// For sunpro, it chokes if time.h is included through stat.h 1.25 +#endif 1.26 + 1.27 +#include <fstream> 1.28 + 1.29 +#ifdef __CYGWIN__ 1.30 +# define __int64 long long 1.31 +#endif 1.32 + 1.33 +#include <cstdio> 1.34 +#if !defined(__ISCPP__) 1.35 +extern "C" { 1.36 +# include <sys/stat.h> 1.37 +} 1.38 +#endif 1.39 + 1.40 +#if defined( __MSL__ ) 1.41 +# include <unix.h> 1.42 +#endif 1.43 + 1.44 +#if defined(__ISCPP__) 1.45 +# include <c_locale_is/filestat.h> 1.46 +#endif 1.47 + 1.48 +#if defined(__BEOS__) && defined(__INTEL__) 1.49 +# include <fcntl.h> 1.50 +# include <sys/stat.h> // For _fstat 1.51 +#endif 1.52 + 1.53 +#if defined (_STLP_MSVC) || defined (__MINGW32__) 1.54 +# include <fcntl.h> 1.55 +# define S_IREAD _S_IREAD 1.56 +# define S_IWRITE _S_IWRITE 1.57 +# define S_IFREG _S_IFREG 1.58 + // map permission masks 1.59 +# ifndef S_IRUSR 1.60 +# define S_IRUSR _S_IREAD 1.61 +# define S_IWUSR _S_IWRITE 1.62 +# endif 1.63 +# ifndef S_IRGRP 1.64 +# define S_IRGRP _S_IREAD 1.65 +# define S_IWGRP _S_IWRITE 1.66 +# endif 1.67 +# ifndef S_IROTH 1.68 +# define S_IROTH _S_IREAD 1.69 +# define S_IWOTH _S_IWRITE 1.70 +# endif 1.71 + 1.72 +# ifndef O_RDONLY 1.73 +# define O_RDONLY _O_RDONLY 1.74 +# define O_WRONLY _O_WRONLY 1.75 +# define O_RDWR _O_RDWR 1.76 +# define O_APPEND _O_APPEND 1.77 +# define O_CREAT _O_CREAT 1.78 +# define O_TRUNC _O_TRUNC 1.79 +# define O_TEXT _O_TEXT 1.80 +# define O_BINARY _O_BINARY 1.81 +# endif 1.82 + 1.83 +# ifndef O_ACCMODE 1.84 +# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 1.85 +# endif 1.86 +#endif 1.87 + 1.88 +const _STLP_fd INVALID_STLP_FD = -1; 1.89 + 1.90 + 1.91 +# ifdef __MSL__ 1.92 +# define _O_TEXT 0x0 1.93 +# if !defined( O_TEXT ) 1.94 +# define O_TEXT _O_TEXT 1.95 +# endif 1.96 +# define _S_IFREG S_IFREG 1.97 +# define S_IREAD S_IRUSR 1.98 +# define S_IWRITE S_IWUSR 1.99 +# define S_IEXEC S_IXUSR 1.100 +# define _S_IWRITE S_IWRITE 1.101 +# define _S_IREAD S_IREAD 1.102 +# define _open open 1.103 +# define _close close 1.104 +# define _read read 1.105 +# define _write write 1.106 +# endif 1.107 + 1.108 +_STLP_BEGIN_NAMESPACE 1.109 + 1.110 +// Compare with streamoff definition in stl/char_traits.h! 1.111 + 1.112 +#if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \ 1.113 + (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE)) 1.114 +# define FOPEN fopen 1.115 +# define FSEEK fseek 1.116 +# define FSTAT fstat 1.117 +# define STAT stat 1.118 +# define FTELL ftell 1.119 +#else 1.120 +# define FOPEN fopen64 1.121 +# define FSEEK fseeko64 1.122 +# define FSTAT fstat64 1.123 +# define STAT stat64 1.124 +# define FTELL ftello64 1.125 +#endif 1.126 + 1.127 +_STLP_MOVE_TO_PRIV_NAMESPACE 1.128 + 1.129 +// Helper functions for _Filebuf_base. 1.130 + 1.131 +static bool __is_regular_file(_STLP_fd fd) { 1.132 + struct STAT buf; 1.133 + return FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0 ; 1.134 +} 1.135 + 1.136 +// Number of characters in the file. 1.137 +static streamoff __file_size(_STLP_fd fd) { 1.138 + streamoff ret = 0; 1.139 + 1.140 + struct STAT buf; 1.141 + if (FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0) 1.142 + ret = buf.st_size > 0 ? buf.st_size : 0; 1.143 + 1.144 + return ret; 1.145 +} 1.146 + 1.147 +_STLP_MOVE_TO_STD_NAMESPACE 1.148 + 1.149 +// All version of Unix have mmap and lseek system calls. Some also have 1.150 +// longer versions of those system calls to accommodate 64-bit offsets. 1.151 +// If we're on a Unix system, define some macros to encapsulate those 1.152 +// differences. 1.153 + 1.154 +size_t _Filebuf_base::_M_page_size = 4096; 1.155 + 1.156 +_Filebuf_base::_Filebuf_base() 1.157 + : _M_file_id(INVALID_STLP_FD), 1.158 + _M_openmode(0), 1.159 + _M_is_open(false), 1.160 + _M_should_close(false) 1.161 +{} 1.162 + 1.163 +void _Filebuf_base::_S_initialize() 1.164 +{ 1.165 + 1.166 +} 1.167 + 1.168 +// Return the size of the file. This is a wrapper for stat. 1.169 +// Returns zero if the size cannot be determined or is ill-defined. 1.170 +streamoff _Filebuf_base::_M_file_size() 1.171 +{ 1.172 + return _STLP_PRIV __file_size(_M_file_id); 1.173 +} 1.174 + 1.175 +bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, 1.176 + long permission) 1.177 +{ 1.178 + _STLP_fd file_no; 1.179 + 1.180 + if (_M_is_open) 1.181 + return false; 1.182 + 1.183 + // use FILE-based i/o 1.184 + const char* flags; 1.185 + 1.186 + switch (openmode & (~ios_base::ate)) { 1.187 + case ios_base::out: 1.188 + case ios_base::out | ios_base::trunc: 1.189 + flags = "w"; 1.190 + break; 1.191 + 1.192 + case ios_base::out | ios_base::binary: 1.193 + case ios_base::out | ios_base::trunc | ios_base::binary: 1.194 + flags = "wb"; 1.195 + break; 1.196 + 1.197 + case ios_base::out | ios_base::app: 1.198 + flags = "a"; 1.199 + break; 1.200 + 1.201 + case ios_base::out | ios_base::app | ios_base::binary: 1.202 + flags = "ab"; 1.203 + break; 1.204 + 1.205 + case ios_base::in: 1.206 + flags = "r"; 1.207 + break; 1.208 + 1.209 + case ios_base::in | ios_base::binary: 1.210 + flags = "rb"; 1.211 + break; 1.212 + 1.213 + case ios_base::in | ios_base::out: 1.214 + flags = "r+"; 1.215 + break; 1.216 + 1.217 + case ios_base::in | ios_base::out | ios_base::binary: 1.218 + flags = "r+b"; 1.219 + break; 1.220 + 1.221 + case ios_base::in | ios_base::out | ios_base::trunc: 1.222 + flags = "w+"; 1.223 + break; 1.224 + 1.225 + case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: 1.226 + flags = "w+b"; 1.227 + break; 1.228 + 1.229 + default: // The above are the only combinations of 1.230 + return false; // flags allowed by the C++ standard. 1.231 + } 1.232 + 1.233 + // fbp : TODO : set permissions ! 1.234 + (void)permission; // currently unused //*TY 02/26/2000 - added to suppress warning message 1.235 + _M_file = FOPEN(name, flags); 1.236 + 1.237 + if (_M_file) { 1.238 + file_no = fileno(_M_file); 1.239 + } else { 1.240 + return false; 1.241 + } 1.242 + 1.243 + // unset buffering immediately 1.244 + setbuf(_M_file, 0); 1.245 + 1.246 + _M_is_open = true; 1.247 + 1.248 + if (openmode & ios_base::ate) { 1.249 + if (FSEEK(_M_file, 0, SEEK_END) != 0) 1.250 + _M_is_open = false; 1.251 + } 1.252 + 1.253 + _M_file_id = file_no; 1.254 + _M_should_close = _M_is_open; 1.255 + _M_openmode = openmode; 1.256 + 1.257 + if (_M_is_open) 1.258 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 1.259 + 1.260 + return (_M_is_open != 0); 1.261 +} 1.262 + 1.263 + 1.264 +bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) 1.265 +{ 1.266 + // This doesn't really grant everyone in the world read/write 1.267 + // access. On Unix, file-creation system calls always clear 1.268 + // bits that are set in the umask from the permissions flag. 1.269 + return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP | 1.270 + S_IWGRP | S_IROTH | S_IWOTH); 1.271 +} 1.272 + 1.273 +// Associated the filebuf with a file descriptor pointing to an already- 1.274 +// open file. Mode is set to be consistent with the way that the file 1.275 +// was opened. 1.276 +bool _Filebuf_base::_M_open( int file_no, ios_base::openmode ) 1.277 +{ 1.278 + if (_M_is_open || file_no < 0) 1.279 + return false; 1.280 + 1.281 + struct STAT buf; 1.282 + if (FSTAT(file_no, &buf) != 0) 1.283 + return false; 1.284 + int mode = buf.st_mode; 1.285 + 1.286 + switch ( mode & (S_IWRITE | S_IREAD) ) { 1.287 + case S_IREAD: 1.288 + _M_openmode = ios_base::in; 1.289 + break; 1.290 + case S_IWRITE: 1.291 + _M_openmode = ios_base::out; 1.292 + break; 1.293 + case (S_IWRITE | S_IREAD): 1.294 + _M_openmode = ios_base::in | ios_base::out; 1.295 + break; 1.296 + default: 1.297 + return false; 1.298 + } 1.299 + _M_file_id = file_no; 1.300 + _M_is_open = true; 1.301 + _M_should_close = false; 1.302 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 1.303 + return true; 1.304 +} 1.305 + 1.306 +bool _Filebuf_base::_M_close() 1.307 +{ 1.308 + if (!_M_is_open) 1.309 + return false; 1.310 + 1.311 + bool ok = _M_should_close ? (fclose(_M_file) == 0) : true; 1.312 + 1.313 + _M_is_open = _M_should_close = false; 1.314 + _M_openmode = 0; 1.315 + return ok; 1.316 +} 1.317 + 1.318 +// Read up to n characters into a buffer. Return value is number of 1.319 +// characters read. 1.320 +ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) { 1.321 + return fread(buf, 1, n, _M_file); 1.322 +} 1.323 + 1.324 +// Write n characters from a buffer. Return value: true if we managed 1.325 +// to write the entire buffer, false if we didn't. 1.326 +bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) 1.327 +{ 1.328 + for (;;) { 1.329 + ptrdiff_t written = fwrite(buf, 1, n, _M_file); 1.330 + 1.331 + if (n == written) { 1.332 + return true; 1.333 + } 1.334 + 1.335 + if (written > 0 && written < n) { 1.336 + n -= written; 1.337 + buf += written; 1.338 + } else { 1.339 + return false; 1.340 + } 1.341 + } 1.342 +} 1.343 + 1.344 +// Wrapper for lseek or the like. 1.345 +streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) 1.346 +{ 1.347 + int whence; 1.348 + 1.349 + switch ( dir ) { 1.350 + case ios_base::beg: 1.351 + if (offset < 0 /* || offset > _M_file_size() */ ) 1.352 + return streamoff(-1); 1.353 + whence = SEEK_SET; 1.354 + break; 1.355 + case ios_base::cur: 1.356 + whence = SEEK_CUR; 1.357 + break; 1.358 + case ios_base::end: 1.359 + if (/* offset > 0 || */ -offset > _M_file_size() ) 1.360 + return streamoff(-1); 1.361 + whence = SEEK_END; 1.362 + break; 1.363 + default: 1.364 + return streamoff(-1); 1.365 + } 1.366 + 1.367 + if ( FSEEK(_M_file, offset, whence) == 0 ) { 1.368 + return FTELL(_M_file); 1.369 + } 1.370 + 1.371 + return streamoff(-1); 1.372 +} 1.373 + 1.374 + 1.375 +// Attempts to memory-map len bytes of the current file, starting 1.376 +// at position offset. Precondition: offset is a multiple of the 1.377 +// page size. Postcondition: return value is a null pointer if the 1.378 +// memory mapping failed. Otherwise the return value is a pointer to 1.379 +// the memory-mapped file and the file position is set to offset. 1.380 +void *_Filebuf_base::_M_mmap(streamoff, streamoff ) 1.381 +{ 1.382 + return 0; 1.383 +} 1.384 + 1.385 +void _Filebuf_base::_M_unmap(void*, streamoff) 1.386 +{ 1.387 + // precondition : there is a valid mapping at the moment 1.388 +} 1.389 + 1.390 +_STLP_END_NAMESPACE