Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfstream_unistd.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 00019 #if defined (__SUNPPRO_CC) && !defined (_STLP_NO_NEW_C_HEADERS) 00020 # include <time.h> 00021 // For sunpro, it chokes if time.h is included through stat.h 00022 #endif 00023 00024 #include <fstream> 00025 00026 #ifdef __CYGWIN__ 00027 # define __int64 long long 00028 #endif 00029 00030 extern "C" { 00031 // open/close/read/write 00032 #include <sys/stat.h> // For stat 00033 #if !defined (_CRAY) && ! defined (__EMX__) 00034 # include <sys/mman.h> // For mmap 00035 #endif 00036 00037 // on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this 00038 #if defined (__hpux) && defined (__GNUC__) 00039 # undef _INCLUDE_POSIX1C_SOURCE 00040 #endif 00041 00042 #include <unistd.h> 00043 #include <fcntl.h> 00044 } 00045 00046 #ifdef __APPLE__ 00047 # include <sys/sysctl.h> 00048 #endif 00049 00050 const _STLP_fd INVALID_STLP_FD = -1; 00051 00052 #ifndef O_ACCMODE 00053 # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 00054 #endif 00055 00056 // Compare with streamoff definition in stl/char_traits.h! 00057 #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \ 00058 (!defined(_LARGEFILE_SOURCE) && !defined (_LARGEFILE64_SOURCE)) 00059 # define FSTAT fstat 00060 # define STAT stat 00061 # define LSEEK lseek 00062 # define MMAP mmap 00063 # define OPEN open 00064 #else 00065 # define FSTAT fstat64 00066 # define STAT stat64 00067 # define LSEEK lseek64 00068 # define MMAP mmap64 00069 # define OPEN open64 00070 #endif 00071 00072 #ifndef MAP_FAILED /* MMAP failure return code */ 00073 # define MAP_FAILED -1 00074 #endif 00075 00076 _STLP_BEGIN_NAMESPACE 00077 00078 static ios_base::openmode flag_to_openmode(int mode) 00079 { 00080 ios_base::openmode ret = ios_base::__default_mode; 00081 00082 switch ( mode & O_ACCMODE ) { 00083 case O_RDONLY: 00084 ret = ios_base::in; 00085 break; 00086 case O_WRONLY: 00087 ret = ios_base::out; 00088 break; 00089 case O_RDWR: 00090 ret = ios_base::in | ios_base::out; 00091 break; 00092 } 00093 00094 if ( mode & O_APPEND ) 00095 ret |= ios_base::app; 00096 00097 return ret; 00098 } 00099 00100 _STLP_MOVE_TO_PRIV_NAMESPACE 00101 00102 // Helper functions for _Filebuf_base. 00103 00104 static bool __is_regular_file(_STLP_fd fd) { 00105 struct STAT buf; 00106 return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode); 00107 } 00108 00109 // Number of characters in the file. 00110 static streamoff __file_size(_STLP_fd fd) { 00111 streamoff ret = 0; 00112 00113 struct STAT buf; 00114 if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode)) 00115 ret = buf.st_size > 0 ? buf.st_size : 0; 00116 00117 return ret; 00118 } 00119 00120 _STLP_MOVE_TO_STD_NAMESPACE 00121 00122 size_t _Filebuf_base::_M_page_size = 4096; 00123 00124 _Filebuf_base::_Filebuf_base() 00125 : _M_file_id(INVALID_STLP_FD), 00126 _M_openmode(0), 00127 _M_is_open(false), 00128 _M_should_close(false) 00129 {} 00130 00131 void _Filebuf_base::_S_initialize() 00132 { 00133 #if defined (__APPLE__) 00134 int mib[2]; 00135 size_t pagesize, len; 00136 mib[0] = CTL_HW; 00137 mib[1] = HW_PAGESIZE; 00138 len = sizeof(pagesize); 00139 sysctl(mib, 2, &pagesize, &len, NULL, 0); 00140 _M_page_size = pagesize; 00141 #elif defined (__DJGPP) && defined (_CRAY) 00142 _M_page_size = BUFSIZ; 00143 #else 00144 _M_page_size = sysconf(_SC_PAGESIZE); 00145 #endif 00146 } 00147 00148 // Return the size of the file. This is a wrapper for stat. 00149 // Returns zero if the size cannot be determined or is ill-defined. 00150 streamoff _Filebuf_base::_M_file_size() 00151 { 00152 return _STLP_PRIV __file_size(_M_file_id); 00153 } 00154 00155 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, 00156 long permission) 00157 { 00158 _STLP_fd file_no; 00159 00160 if (_M_is_open) 00161 return false; 00162 00163 int flags = 0; 00164 00165 // Unix makes no distinction between text and binary files. 00166 switch ( openmode & (~ios_base::ate & ~ios_base::binary) ) { 00167 case ios_base::out: 00168 case ios_base::out | ios_base::trunc: 00169 flags = O_WRONLY | O_CREAT | O_TRUNC; 00170 break; 00171 case ios_base::app: 00172 case ios_base::out | ios_base::app: 00173 flags = O_WRONLY | O_CREAT | O_APPEND; 00174 break; 00175 case ios_base::in: 00176 flags = O_RDONLY; 00177 permission = 0; // Irrelevant unless we're writing. 00178 break; 00179 case ios_base::in | ios_base::out: 00180 flags = O_RDWR; 00181 break; 00182 case ios_base::in | ios_base::out | ios_base::trunc: 00183 flags = O_RDWR | O_CREAT | O_TRUNC; 00184 break; 00185 case ios_base::in | ios_base::app: 00186 case ios_base::in | ios_base::out | ios_base::app: 00187 flags = O_RDWR | O_CREAT | O_APPEND; 00188 break; 00189 default: // The above are the only combinations of 00190 return false; // flags allowed by the C++ standard. 00191 } 00192 00193 file_no = OPEN(name, flags, permission); 00194 00195 if (file_no < 0) 00196 return false; 00197 00198 _M_is_open = true; 00199 00200 if ((openmode & (ios_base::ate | ios_base::app)) && (LSEEK(file_no, 0, SEEK_END) == -1)) { 00201 _M_is_open = false; 00202 } 00203 00204 _M_file_id = file_no; 00205 _M_should_close = _M_is_open; 00206 _M_openmode = openmode; 00207 00208 if (_M_is_open) 00209 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 00210 00211 return (_M_is_open != 0); 00212 } 00213 00214 00215 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) 00216 { 00217 // This doesn't really grant everyone in the world read/write 00218 // access. On Unix, file-creation system calls always clear 00219 // bits that are set in the umask from the permissions flag. 00220 return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP | 00221 S_IWGRP | S_IROTH | S_IWOTH); 00222 } 00223 00224 // Associated the filebuf with a file descriptor pointing to an already- 00225 // open file. Mode is set to be consistent with the way that the file 00226 // was opened. 00227 bool _Filebuf_base::_M_open(int file_no, ios_base::openmode) 00228 { 00229 if (_M_is_open || file_no < 0) 00230 return false; 00231 00232 int mode = fcntl(file_no, F_GETFL); 00233 00234 if (mode == -1) 00235 return false; 00236 00237 _M_openmode = flag_to_openmode(mode); 00238 _M_file_id = file_no; 00239 00240 _M_is_open = true; 00241 _M_should_close = false; 00242 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 00243 return true; 00244 } 00245 00246 bool _Filebuf_base::_M_close() 00247 { 00248 if (!_M_is_open) 00249 return false; 00250 00251 bool ok = _M_should_close ? (close(_M_file_id) == 0) : true; 00252 00253 _M_is_open = _M_should_close = false; 00254 _M_openmode = 0; 00255 return ok; 00256 } 00257 00258 // Read up to n characters into a buffer. Return value is number of 00259 // characters read. 00260 ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) 00261 { 00262 return read(_M_file_id, buf, n); 00263 } 00264 00265 // Write n characters from a buffer. Return value: true if we managed 00266 // to write the entire buffer, false if we didn't. 00267 bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) 00268 { 00269 for (;;) { 00270 ptrdiff_t written = write(_M_file_id, buf, n); 00271 00272 if (n == written) { 00273 return true; 00274 } 00275 00276 if (written > 0 && written < n) { 00277 n -= written; 00278 buf += written; 00279 } else { 00280 return false; 00281 } 00282 } 00283 } 00284 00285 // Wrapper for lseek or the like. 00286 streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) 00287 { 00288 int whence; 00289 00290 switch ( dir ) { 00291 case ios_base::beg: 00292 if (offset < 0 /* || offset > _M_file_size() */ ) 00293 return streamoff(-1); 00294 whence = SEEK_SET; 00295 break; 00296 case ios_base::cur: 00297 whence = SEEK_CUR; 00298 break; 00299 case ios_base::end: 00300 if (/* offset > 0 || */ -offset > _M_file_size() ) 00301 return streamoff(-1); 00302 whence = SEEK_END; 00303 break; 00304 default: 00305 return streamoff(-1); 00306 } 00307 00308 return LSEEK(_M_file_id, offset, whence); 00309 } 00310 00311 // Attempts to memory-map len bytes of the current file, starting 00312 // at position offset. Precondition: offset is a multiple of the 00313 // page size. Postcondition: return value is a null pointer if the 00314 // memory mapping failed. Otherwise the return value is a pointer to 00315 // the memory-mapped file and the file position is set to offset. 00316 void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) 00317 { 00318 void* base; 00319 #if !defined (__DJGPP) && !defined (_CRAY) 00320 base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset); 00321 if (base != (void*)MAP_FAILED) { 00322 if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) { 00323 this->_M_unmap(base, len); 00324 base = 0; 00325 } 00326 } else 00327 base =0; 00328 #else 00329 _STLP_MARK_PARAMETER_AS_UNUSED(&offset) 00330 _STLP_MARK_PARAMETER_AS_UNUSED(&len) 00331 base = 0; 00332 #endif 00333 return base; 00334 } 00335 00336 void _Filebuf_base::_M_unmap(void* base, streamoff len) 00337 { 00338 // precondition : there is a valid mapping at the moment 00339 #if !defined (__DJGPP) && !defined (_CRAY) 00340 munmap((char*)base, len); 00341 #else 00342 _STLP_MARK_PARAMETER_AS_UNUSED(&len) 00343 _STLP_MARK_PARAMETER_AS_UNUSED(base) 00344 #endif 00345 } 00346 00347 _STLP_END_NAMESPACE Generated on Fri May 25 2012 04:33:39 for ReactOS by
1.7.6.1
|