1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/stlport/src/details/fstream_unistd.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,347 @@ 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 +extern "C" { 1.34 +// open/close/read/write 1.35 +#include <sys/stat.h> // For stat 1.36 +#if !defined (_CRAY) && ! defined (__EMX__) 1.37 +# include <sys/mman.h> // For mmap 1.38 +#endif 1.39 + 1.40 +// on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this 1.41 +#if defined (__hpux) && defined (__GNUC__) 1.42 +# undef _INCLUDE_POSIX1C_SOURCE 1.43 +#endif 1.44 + 1.45 +#include <unistd.h> 1.46 +#include <fcntl.h> 1.47 +} 1.48 + 1.49 +#ifdef __APPLE__ 1.50 +# include <sys/sysctl.h> 1.51 +#endif 1.52 + 1.53 +const _STLP_fd INVALID_STLP_FD = -1; 1.54 + 1.55 +#ifndef O_ACCMODE 1.56 +# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 1.57 +#endif 1.58 + 1.59 +// Compare with streamoff definition in stl/char_traits.h! 1.60 +#if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \ 1.61 + (!defined(_LARGEFILE_SOURCE) && !defined (_LARGEFILE64_SOURCE)) 1.62 +# define FSTAT fstat 1.63 +# define STAT stat 1.64 +# define LSEEK lseek 1.65 +# define MMAP mmap 1.66 +# define OPEN open 1.67 +#else 1.68 +# define FSTAT fstat64 1.69 +# define STAT stat64 1.70 +# define LSEEK lseek64 1.71 +# define MMAP mmap64 1.72 +# define OPEN open64 1.73 +#endif 1.74 + 1.75 +#ifndef MAP_FAILED /* MMAP failure return code */ 1.76 +# define MAP_FAILED -1 1.77 +#endif 1.78 + 1.79 +_STLP_BEGIN_NAMESPACE 1.80 + 1.81 +static ios_base::openmode flag_to_openmode(int mode) 1.82 +{ 1.83 + ios_base::openmode ret = ios_base::__default_mode; 1.84 + 1.85 + switch ( mode & O_ACCMODE ) { 1.86 + case O_RDONLY: 1.87 + ret = ios_base::in; 1.88 + break; 1.89 + case O_WRONLY: 1.90 + ret = ios_base::out; 1.91 + break; 1.92 + case O_RDWR: 1.93 + ret = ios_base::in | ios_base::out; 1.94 + break; 1.95 + } 1.96 + 1.97 + if ( mode & O_APPEND ) 1.98 + ret |= ios_base::app; 1.99 + 1.100 + return ret; 1.101 +} 1.102 + 1.103 +_STLP_MOVE_TO_PRIV_NAMESPACE 1.104 + 1.105 +// Helper functions for _Filebuf_base. 1.106 + 1.107 +static bool __is_regular_file(_STLP_fd fd) { 1.108 + struct STAT buf; 1.109 + return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode); 1.110 +} 1.111 + 1.112 +// Number of characters in the file. 1.113 +static streamoff __file_size(_STLP_fd fd) { 1.114 + streamoff ret = 0; 1.115 + 1.116 + struct STAT buf; 1.117 + if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode)) 1.118 + ret = buf.st_size > 0 ? buf.st_size : 0; 1.119 + 1.120 + return ret; 1.121 +} 1.122 + 1.123 +_STLP_MOVE_TO_STD_NAMESPACE 1.124 + 1.125 +size_t _Filebuf_base::_M_page_size = 4096; 1.126 + 1.127 +_Filebuf_base::_Filebuf_base() 1.128 + : _M_file_id(INVALID_STLP_FD), 1.129 + _M_openmode(0), 1.130 + _M_is_open(false), 1.131 + _M_should_close(false) 1.132 +{} 1.133 + 1.134 +void _Filebuf_base::_S_initialize() 1.135 +{ 1.136 +#if defined (__APPLE__) 1.137 + int mib[2]; 1.138 + size_t pagesize, len; 1.139 + mib[0] = CTL_HW; 1.140 + mib[1] = HW_PAGESIZE; 1.141 + len = sizeof(pagesize); 1.142 + sysctl(mib, 2, &pagesize, &len, NULL, 0); 1.143 + _M_page_size = pagesize; 1.144 +#elif defined (__DJGPP) && defined (_CRAY) 1.145 + _M_page_size = BUFSIZ; 1.146 +#else 1.147 + _M_page_size = sysconf(_SC_PAGESIZE); 1.148 +#endif 1.149 +} 1.150 + 1.151 +// Return the size of the file. This is a wrapper for stat. 1.152 +// Returns zero if the size cannot be determined or is ill-defined. 1.153 +streamoff _Filebuf_base::_M_file_size() 1.154 +{ 1.155 + return _STLP_PRIV __file_size(_M_file_id); 1.156 +} 1.157 + 1.158 +bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, 1.159 + long permission) 1.160 +{ 1.161 + _STLP_fd file_no; 1.162 + 1.163 + if (_M_is_open) 1.164 + return false; 1.165 + 1.166 + int flags = 0; 1.167 + 1.168 + // Unix makes no distinction between text and binary files. 1.169 + switch ( openmode & (~ios_base::ate & ~ios_base::binary) ) { 1.170 + case ios_base::out: 1.171 + case ios_base::out | ios_base::trunc: 1.172 + flags = O_WRONLY | O_CREAT | O_TRUNC; 1.173 + break; 1.174 + case ios_base::app: 1.175 + case ios_base::out | ios_base::app: 1.176 + flags = O_WRONLY | O_CREAT | O_APPEND; 1.177 + break; 1.178 + case ios_base::in: 1.179 + flags = O_RDONLY; 1.180 + permission = 0; // Irrelevant unless we're writing. 1.181 + break; 1.182 + case ios_base::in | ios_base::out: 1.183 + flags = O_RDWR; 1.184 + break; 1.185 + case ios_base::in | ios_base::out | ios_base::trunc: 1.186 + flags = O_RDWR | O_CREAT | O_TRUNC; 1.187 + break; 1.188 + case ios_base::in | ios_base::app: 1.189 + case ios_base::in | ios_base::out | ios_base::app: 1.190 + flags = O_RDWR | O_CREAT | O_APPEND; 1.191 + break; 1.192 + default: // The above are the only combinations of 1.193 + return false; // flags allowed by the C++ standard. 1.194 + } 1.195 + 1.196 + file_no = OPEN(name, flags, permission); 1.197 + 1.198 + if (file_no < 0) 1.199 + return false; 1.200 + 1.201 + _M_is_open = true; 1.202 + 1.203 + if ((openmode & (ios_base::ate | ios_base::app)) && (LSEEK(file_no, 0, SEEK_END) == -1)) { 1.204 + _M_is_open = false; 1.205 + } 1.206 + 1.207 + _M_file_id = file_no; 1.208 + _M_should_close = _M_is_open; 1.209 + _M_openmode = openmode; 1.210 + 1.211 + if (_M_is_open) 1.212 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 1.213 + 1.214 + return (_M_is_open != 0); 1.215 +} 1.216 + 1.217 + 1.218 +bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) 1.219 +{ 1.220 + // This doesn't really grant everyone in the world read/write 1.221 + // access. On Unix, file-creation system calls always clear 1.222 + // bits that are set in the umask from the permissions flag. 1.223 + return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP | 1.224 + S_IWGRP | S_IROTH | S_IWOTH); 1.225 +} 1.226 + 1.227 +// Associated the filebuf with a file descriptor pointing to an already- 1.228 +// open file. Mode is set to be consistent with the way that the file 1.229 +// was opened. 1.230 +bool _Filebuf_base::_M_open(int file_no, ios_base::openmode) 1.231 +{ 1.232 + if (_M_is_open || file_no < 0) 1.233 + return false; 1.234 + 1.235 + int mode = fcntl(file_no, F_GETFL); 1.236 + 1.237 + if (mode == -1) 1.238 + return false; 1.239 + 1.240 + _M_openmode = flag_to_openmode(mode); 1.241 + _M_file_id = file_no; 1.242 + 1.243 + _M_is_open = true; 1.244 + _M_should_close = false; 1.245 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 1.246 + return true; 1.247 +} 1.248 + 1.249 +bool _Filebuf_base::_M_close() 1.250 +{ 1.251 + if (!_M_is_open) 1.252 + return false; 1.253 + 1.254 + bool ok = _M_should_close ? (close(_M_file_id) == 0) : true; 1.255 + 1.256 + _M_is_open = _M_should_close = false; 1.257 + _M_openmode = 0; 1.258 + return ok; 1.259 +} 1.260 + 1.261 +// Read up to n characters into a buffer. Return value is number of 1.262 +// characters read. 1.263 +ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) 1.264 +{ 1.265 + return read(_M_file_id, buf, n); 1.266 +} 1.267 + 1.268 +// Write n characters from a buffer. Return value: true if we managed 1.269 +// to write the entire buffer, false if we didn't. 1.270 +bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) 1.271 +{ 1.272 + for (;;) { 1.273 + ptrdiff_t written = write(_M_file_id, buf, n); 1.274 + 1.275 + if (n == written) { 1.276 + return true; 1.277 + } 1.278 + 1.279 + if (written > 0 && written < n) { 1.280 + n -= written; 1.281 + buf += written; 1.282 + } else { 1.283 + return false; 1.284 + } 1.285 + } 1.286 +} 1.287 + 1.288 +// Wrapper for lseek or the like. 1.289 +streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) 1.290 +{ 1.291 + int whence; 1.292 + 1.293 + switch ( dir ) { 1.294 + case ios_base::beg: 1.295 + if (offset < 0 /* || offset > _M_file_size() */ ) 1.296 + return streamoff(-1); 1.297 + whence = SEEK_SET; 1.298 + break; 1.299 + case ios_base::cur: 1.300 + whence = SEEK_CUR; 1.301 + break; 1.302 + case ios_base::end: 1.303 + if (/* offset > 0 || */ -offset > _M_file_size() ) 1.304 + return streamoff(-1); 1.305 + whence = SEEK_END; 1.306 + break; 1.307 + default: 1.308 + return streamoff(-1); 1.309 + } 1.310 + 1.311 + return LSEEK(_M_file_id, offset, whence); 1.312 +} 1.313 + 1.314 +// Attempts to memory-map len bytes of the current file, starting 1.315 +// at position offset. Precondition: offset is a multiple of the 1.316 +// page size. Postcondition: return value is a null pointer if the 1.317 +// memory mapping failed. Otherwise the return value is a pointer to 1.318 +// the memory-mapped file and the file position is set to offset. 1.319 +void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) 1.320 +{ 1.321 + void* base; 1.322 +#if !defined (__DJGPP) && !defined (_CRAY) 1.323 + base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset); 1.324 + if (base != (void*)MAP_FAILED) { 1.325 + if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) { 1.326 + this->_M_unmap(base, len); 1.327 + base = 0; 1.328 + } 1.329 + } else 1.330 + base =0; 1.331 +#else 1.332 + _STLP_MARK_PARAMETER_AS_UNUSED(&offset) 1.333 + _STLP_MARK_PARAMETER_AS_UNUSED(&len) 1.334 + base = 0; 1.335 +#endif 1.336 + return base; 1.337 +} 1.338 + 1.339 +void _Filebuf_base::_M_unmap(void* base, streamoff len) 1.340 +{ 1.341 + // precondition : there is a valid mapping at the moment 1.342 +#if !defined (__DJGPP) && !defined (_CRAY) 1.343 + munmap((char*)base, len); 1.344 +#else 1.345 + _STLP_MARK_PARAMETER_AS_UNUSED(&len) 1.346 + _STLP_MARK_PARAMETER_AS_UNUSED(base) 1.347 +#endif 1.348 +} 1.349 + 1.350 +_STLP_END_NAMESPACE