ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fstream_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.