fstream_unistd.cpp

来自「stl的源码」· C++ 代码 · 共 348 行

CPP
348
字号
/* * Copyright (c) 1999 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */#if defined  (__SUNPPRO_CC)  && !defined (_STLP_NO_NEW_C_HEADERS)#  include <time.h>// For sunpro, it chokes if time.h is included through stat.h#endif#include <fstream>#ifdef __CYGWIN__#  define __int64 long long#endifextern "C" {// open/close/read/write#include <sys/stat.h>           // For stat#if !defined (_CRAY) && ! defined (__EMX__)#  include <sys/mman.h>           // For mmap#endif//  on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this#if defined (__hpux) && defined (__GNUC__)#  undef _INCLUDE_POSIX1C_SOURCE#endif#include <unistd.h>#include <fcntl.h>}#ifdef __APPLE__#  include <sys/sysctl.h>#endifconst _STLP_fd INVALID_STLP_FD = -1;#ifndef O_ACCMODE#  define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)#endif// Compare with streamoff definition in stl/char_traits.h!#if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \    (!defined(_LARGEFILE_SOURCE) && !defined (_LARGEFILE64_SOURCE))#  define FSTAT fstat#  define STAT  stat#  define LSEEK lseek#  define MMAP  mmap#  define OPEN  open#else#  define FSTAT fstat64#  define STAT  stat64#  define LSEEK lseek64#  define MMAP  mmap64#  define OPEN  open64#endif#ifndef MAP_FAILED /* MMAP failure return code */#  define MAP_FAILED -1#endif_STLP_BEGIN_NAMESPACEstatic ios_base::openmode flag_to_openmode(int mode){  ios_base::openmode ret = ios_base::__default_mode;  switch ( mode & O_ACCMODE ) {    case O_RDONLY:      ret = ios_base::in;      break;    case O_WRONLY:      ret = ios_base::out;      break;    case O_RDWR:      ret = ios_base::in | ios_base::out;      break;  }  if ( mode & O_APPEND )    ret |= ios_base::app;  return ret;}_STLP_MOVE_TO_PRIV_NAMESPACE// Helper functions for _Filebuf_base.static bool __is_regular_file(_STLP_fd fd) {  struct STAT buf;  return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode);}// Number of characters in the file.static streamoff __file_size(_STLP_fd fd) {  streamoff ret = 0;  struct STAT buf;  if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode))    ret = buf.st_size > 0 ? buf.st_size : 0;  return ret;}_STLP_MOVE_TO_STD_NAMESPACEsize_t _Filebuf_base::_M_page_size = 4096;_Filebuf_base::_Filebuf_base()  : _M_file_id(INVALID_STLP_FD),    _M_openmode(0),    _M_is_open(false),    _M_should_close(false){}void _Filebuf_base::_S_initialize(){#if defined (__APPLE__)  int mib[2];  size_t pagesize, len;  mib[0] = CTL_HW;  mib[1] = HW_PAGESIZE;  len = sizeof(pagesize);  sysctl(mib, 2, &pagesize, &len, NULL, 0);  _M_page_size = pagesize;#elif defined (__DJGPP) && defined (_CRAY)  _M_page_size = BUFSIZ;#else  _M_page_size = sysconf(_SC_PAGESIZE);#endif}// Return the size of the file.  This is a wrapper for stat.// Returns zero if the size cannot be determined or is ill-defined.streamoff _Filebuf_base::_M_file_size(){  return _STLP_PRIV __file_size(_M_file_id);}bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,                            long permission){  _STLP_fd file_no;  if (_M_is_open)    return false;  int flags = 0;  // Unix makes no distinction between text and binary files.  switch ( openmode & (~ios_base::ate & ~ios_base::binary) ) {    case ios_base::out:    case ios_base::out | ios_base::trunc:      flags = O_WRONLY | O_CREAT | O_TRUNC;      break;    case ios_base::app:    case ios_base::out | ios_base::app:      flags = O_WRONLY | O_CREAT | O_APPEND;      break;    case ios_base::in:      flags = O_RDONLY;      permission = 0;             // Irrelevant unless we're writing.      break;    case ios_base::in | ios_base::out:      flags = O_RDWR;      break;    case ios_base::in | ios_base::out | ios_base::trunc:      flags = O_RDWR | O_CREAT | O_TRUNC;      break;    case ios_base::in | ios_base::app:    case ios_base::in | ios_base::out | ios_base::app:      flags = O_RDWR | O_CREAT | O_APPEND;      break;    default:                      // The above are the only combinations of      return false;               // flags allowed by the C++ standard.  }  file_no = OPEN(name, flags, permission);  if (file_no < 0)    return false;  _M_is_open = true;  if ((openmode & (ios_base::ate | ios_base::app)) && (LSEEK(file_no, 0, SEEK_END) == -1)) {    _M_is_open = false;  }  _M_file_id = file_no;  _M_should_close = _M_is_open;  _M_openmode = openmode;  if (_M_is_open)    _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);  return (_M_is_open != 0);}bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode){  // This doesn't really grant everyone in the world read/write  // access.  On Unix, file-creation system calls always clear  // bits that are set in the umask from the permissions flag.  return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP |                                       S_IWGRP | S_IROTH | S_IWOTH);}// Associated the filebuf with a file descriptor pointing to an already-// open file.  Mode is set to be consistent with the way that the file// was opened.bool _Filebuf_base::_M_open(int file_no, ios_base::openmode){  if (_M_is_open || file_no < 0)    return false;  int mode = fcntl(file_no, F_GETFL);  if (mode == -1)    return false;  _M_openmode = flag_to_openmode(mode);  _M_file_id = file_no;  _M_is_open = true;  _M_should_close = false;  _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);  return true;}bool _Filebuf_base::_M_close(){  if (!_M_is_open)    return false;  bool ok = _M_should_close ? (close(_M_file_id) == 0) : true;  _M_is_open = _M_should_close = false;  _M_openmode = 0;  return ok;}// Read up to n characters into a buffer.  Return value is number of// characters read.ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n){  return read(_M_file_id, buf, n);}// Write n characters from a buffer.  Return value: true if we managed// to write the entire buffer, false if we didn't.bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n){  for (;;) {    ptrdiff_t written = write(_M_file_id, buf, n);    if (n == written) {      return true;    }    if (written > 0 && written < n) {      n -= written;      buf += written;    } else {      return false;    }  }}// Wrapper for lseek or the like.streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir){  int whence;  switch ( dir ) {    case ios_base::beg:      if (offset < 0 /* || offset > _M_file_size() */ )        return streamoff(-1);      whence = SEEK_SET;      break;    case ios_base::cur:      whence = SEEK_CUR;      break;    case ios_base::end:      if (/* offset > 0 || */  -offset > _M_file_size() )        return streamoff(-1);      whence = SEEK_END;      break;    default:      return streamoff(-1);  }  return LSEEK(_M_file_id, offset, whence);}// Attempts to memory-map len bytes of the current file, starting// at position offset.  Precondition: offset is a multiple of the// page size.  Postcondition: return value is a null pointer if the// memory mapping failed.  Otherwise the return value is a pointer to// the memory-mapped file and the file position is set to offset.void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len){  void* base;#if !defined (__DJGPP) && !defined (_CRAY)  base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset);  if (base != (void*)MAP_FAILED) {    if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) {      this->_M_unmap(base, len);      base = 0;    }  } else    base =0;#else  _STLP_MARK_PARAMETER_AS_UNUSED(&offset)  _STLP_MARK_PARAMETER_AS_UNUSED(&len)  base = 0;#endif  return base;}void _Filebuf_base::_M_unmap(void* base, streamoff len){  // precondition : there is a valid mapping at the moment#if !defined (__DJGPP) && !defined (_CRAY)  munmap((char*)base, len);#else  _STLP_MARK_PARAMETER_AS_UNUSED(&len)  _STLP_MARK_PARAMETER_AS_UNUSED(base)#endif}_STLP_END_NAMESPACE

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?