123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- /*
- * 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
- #endif
- #include <cstdio>
- #if !defined(__ISCPP__)
- extern "C" {
- # include <sys/stat.h>
- }
- #endif
- #if defined( __MSL__ )
- # include <unix.h>
- #endif
- #if defined(__ISCPP__)
- # include <c_locale_is/filestat.h>
- #endif
- #if defined(__BEOS__) && defined(__INTEL__)
- # include <fcntl.h>
- # include <sys/stat.h> // For _fstat
- #endif
- #if defined (_STLP_MSVC) || defined (__MINGW32__)
- # include <fcntl.h>
- # define S_IREAD _S_IREAD
- # define S_IWRITE _S_IWRITE
- # define S_IFREG _S_IFREG
- // map permission masks
- # ifndef S_IRUSR
- # define S_IRUSR _S_IREAD
- # define S_IWUSR _S_IWRITE
- # endif
- # ifndef S_IRGRP
- # define S_IRGRP _S_IREAD
- # define S_IWGRP _S_IWRITE
- # endif
- # ifndef S_IROTH
- # define S_IROTH _S_IREAD
- # define S_IWOTH _S_IWRITE
- # endif
- # ifndef O_RDONLY
- # define O_RDONLY _O_RDONLY
- # define O_WRONLY _O_WRONLY
- # define O_RDWR _O_RDWR
- # define O_APPEND _O_APPEND
- # define O_CREAT _O_CREAT
- # define O_TRUNC _O_TRUNC
- # define O_TEXT _O_TEXT
- # define O_BINARY _O_BINARY
- # endif
- # ifndef O_ACCMODE
- # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
- # endif
- #endif
- const _STLP_fd INVALID_STLP_FD = -1;
- # ifdef __MSL__
- # define _O_TEXT 0x0
- # if !defined( O_TEXT )
- # define O_TEXT _O_TEXT
- # endif
- # define _S_IFREG S_IFREG
- # define S_IREAD S_IRUSR
- # define S_IWRITE S_IWUSR
- # define S_IEXEC S_IXUSR
- # define _S_IWRITE S_IWRITE
- # define _S_IREAD S_IREAD
- # define _open open
- # define _close close
- # define _read read
- # define _write write
- # endif
- _STLP_BEGIN_NAMESPACE
- // Compare with streamoff definition in stl/char_traits.h!
- #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \
- (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE))
- # define FOPEN fopen
- # define FSEEK fseek
- # define FSTAT fstat
- # define STAT stat
- # define FTELL ftell
- #else
- # define FOPEN fopen64
- # define FSEEK fseeko64
- # define FSTAT fstat64
- # define STAT stat64
- # define FTELL ftello64
- #endif
- _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 && (buf.st_mode & S_IFREG) != 0 ;
- }
- // Number of characters in the file.
- static streamoff __file_size(_STLP_fd fd) {
- streamoff ret = 0;
- struct STAT buf;
- if (FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0)
- ret = buf.st_size > 0 ? buf.st_size : 0;
- return ret;
- }
- _STLP_MOVE_TO_STD_NAMESPACE
- // All version of Unix have mmap and lseek system calls. Some also have
- // longer versions of those system calls to accommodate 64-bit offsets.
- // If we're on a Unix system, define some macros to encapsulate those
- // differences.
- size_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()
- {
- }
- // 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;
- // use FILE-based i/o
- const char* flags;
- switch (openmode & (~ios_base::ate)) {
- case ios_base::out:
- case ios_base::out | ios_base::trunc:
- flags = "w";
- break;
- case ios_base::out | ios_base::binary:
- case ios_base::out | ios_base::trunc | ios_base::binary:
- flags = "wb";
- break;
- case ios_base::out | ios_base::app:
- flags = "a";
- break;
- case ios_base::out | ios_base::app | ios_base::binary:
- flags = "ab";
- break;
- case ios_base::in:
- flags = "r";
- break;
- case ios_base::in | ios_base::binary:
- flags = "rb";
- break;
- case ios_base::in | ios_base::out:
- flags = "r+";
- break;
- case ios_base::in | ios_base::out | ios_base::binary:
- flags = "r+b";
- break;
- case ios_base::in | ios_base::out | ios_base::trunc:
- flags = "w+";
- break;
- case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
- flags = "w+b";
- break;
- default: // The above are the only combinations of
- return false; // flags allowed by the C++ standard.
- }
- // fbp : TODO : set permissions !
- (void)permission; // currently unused //*TY 02/26/2000 - added to suppress warning message
- _M_file = FOPEN(name, flags);
- if (_M_file) {
- file_no = fileno(_M_file);
- } else {
- return false;
- }
- // unset buffering immediately
- setbuf(_M_file, 0);
- _M_is_open = true;
- if (openmode & ios_base::ate) {
- if (FSEEK(_M_file, 0, SEEK_END) != 0)
- _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;
- struct STAT buf;
- if (FSTAT(file_no, &buf) != 0)
- return false;
- int mode = buf.st_mode;
- switch ( mode & (S_IWRITE | S_IREAD) ) {
- case S_IREAD:
- _M_openmode = ios_base::in;
- break;
- case S_IWRITE:
- _M_openmode = ios_base::out;
- break;
- case (S_IWRITE | S_IREAD):
- _M_openmode = ios_base::in | ios_base::out;
- break;
- default:
- return false;
- }
- _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 ? (fclose(_M_file) == 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 fread(buf, 1, n, _M_file);
- }
- // 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 = fwrite(buf, 1, n, _M_file);
- 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);
- }
- if ( FSEEK(_M_file, offset, whence) == 0 ) {
- return FTELL(_M_file);
- }
- return streamoff(-1);
- }
- // 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, streamoff )
- {
- return 0;
- }
- void _Filebuf_base::_M_unmap(void*, streamoff)
- {
- // precondition : there is a valid mapping at the moment
- }
- _STLP_END_NAMESPACE
|