diff options
Diffstat (limited to 'lib/prstreams/prstrms.cpp')
-rw-r--r-- | lib/prstreams/prstrms.cpp | 772 |
1 files changed, 371 insertions, 401 deletions
diff --git a/lib/prstreams/prstrms.cpp b/lib/prstreams/prstrms.cpp index 9f709c06..d601fce2 100644 --- a/lib/prstreams/prstrms.cpp +++ b/lib/prstreams/prstrms.cpp @@ -1,546 +1,516 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape Portable Runtime (NSPR). - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * Robin J. Maxwell 11-22-96 + * Fredrik Roubert <roubert@google.com> 2010-07-23 + * Matt Austern <austern@google.com> 2010-07-23 */ #include "prstrms.h" -#include <string.h> // memmove - -// -// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C. -// -// _PRSTR_BP is the protected member of class ios that is returned -// by the public method rdbuf(). -// -// _PRSTR_DELBUF is the method or data member of class ios, if available, -// with which we can ensure that the ios destructor does not delete -// the associated streambuf. If such a method or data member does not -// exist, define _PRSTR_DELBUF to be empty. -// -// _PRSTR_DELBUF_C is just _PRSTR_DELBUF qualified by a base class. -// - -#if defined(__GNUC__) -#define _PRSTR_BP _strbuf -#define _PRSTR_DELBUF(x) /* as nothing */ -#define _PRSTR_DELBUF_C(c, x) /* as nothing */ -#elif defined(WIN32) -#define _PRSTR_BP bp -#define _PRSTR_DELBUF(x) delbuf(x) -#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x) -#elif defined(OSF1) -#define _PRSTR_BP m_psb -#define _PRSTR_DELBUF(x) /* as nothing */ -#define _PRSTR_DELBUF_C(c, x) /* as nothing */ -#elif defined(QNX) -#define PRFSTREAMS_BROKEN -#else -#define _PRSTR_BP bp -// Unix compilers don't believe in encapsulation -// At least on Solaris this is also ignored -#define _PRSTR_DELBUF(x) delbuf = x -#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x) -#endif - -const PRIntn STRM_BUFSIZ = 8192; - -#if !defined (PRFSTREAMS_BROKEN) + +#include <cstdio> +#include <cstring> +#include <ios> +#include <new> + +using std::ios_base; +using std::iostream; +using std::istream; +using std::nothrow; +using std::ostream; +using std::streambuf; +using std::streamsize; + PRfilebuf::PRfilebuf(): -_fd(0), -_opened(PR_FALSE), -_allocated(PR_FALSE) -{ -} + _fd(NULL), + _opened(false), + _allocated(false), + _unbuffered(false), + _user_buf(false), + _buf_base(NULL), + _buf_end(NULL) { } + PRfilebuf::PRfilebuf(PRFileDesc *fd): -streambuf(), -_fd(fd), -_opened(PR_FALSE), -_allocated(PR_FALSE) -{ -} + _fd(fd), + _opened(false), + _allocated(false), + _unbuffered(false), + _user_buf(false), + _buf_base(NULL), + _buf_end(NULL) { } + -PRfilebuf::PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen): -_fd(fd), -_opened(PR_FALSE), -_allocated(PR_FALSE) +PRfilebuf::PRfilebuf(PRFileDesc *fd, char_type *ptr, streamsize len): + _fd(fd), + _opened(false), + _allocated(false), + _unbuffered(false), + _user_buf(false), + _buf_base(NULL), + _buf_end(NULL) { - PRfilebuf::setbuf(buffptr, bufflen); + setbuf(ptr, len); } + PRfilebuf::~PRfilebuf() { - if (_opened){ + if (_opened) { close(); - }else + } else { sync(); - if (_allocated) - delete base(); -} - -PRfilebuf* -PRfilebuf::open(const char *name, int mode, int flags) -{ - if (_fd != 0) - return 0; // error if already open - PRIntn PRmode = 0; - // translate mode argument - if (!(mode & ios::nocreate)) - PRmode |= PR_CREATE_FILE; - //if (mode & ios::noreplace) - // PRmode |= O_EXCL; - if (mode & ios::app){ - mode |= ios::out; - PRmode |= PR_APPEND; - } - if (mode & ios::trunc){ - mode |= ios::out; // IMPLIED - PRmode |= PR_TRUNCATE; - } - if (mode & ios::out){ - if (mode & ios::in) - PRmode |= PR_RDWR; - else - PRmode |= PR_WRONLY; - if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace))){ - mode |= ios::trunc; // IMPLIED - PRmode |= PR_TRUNCATE; - } - }else if (mode & ios::in) - PRmode |= PR_RDONLY; - else - return 0; // error if not ios:in or ios::out - - - // - // The usual portable across unix crap... - // NT gets a hokey piece of junk layer that prevents - // access to the API. -#ifdef WIN32 - _fd = PR_Open(name, PRmode, PRmode); -#else - _fd = PR_Open(name, PRmode, flags); -#endif - if (_fd == 0) - return 0; - _opened = PR_TRUE; - if ((!unbuffered()) && (!ebuf())){ - char * sbuf = new char[STRM_BUFSIZ]; - if (!sbuf) - unbuffered(1); - else{ - _allocated = PR_TRUE; - streambuf::setb(sbuf,sbuf+STRM_BUFSIZ,0); - } - } - if (mode & ios::ate){ - if (seekoff(0,ios::end,mode)==EOF){ - close(); - return 0; - } } + if (_allocated) { + delete _buf_base; + } +} + + +PRfilebuf *PRfilebuf::open( + const char *name, ios_base::openmode flags, PRIntn mode) +{ + if (_fd != NULL) { + return NULL; // Error if already open. + } + + // Translate flags argument. + PRIntn prflags = 0; + bool ate = (flags & ios_base::ate) != 0; + flags &= ~(ios_base::ate | ios_base::binary); + + // TODO: The flag PR_CREATE_FILE should probably be used for the cases + // (out), (out|app), (out|trunc) and (in|out|trunc) as the C++ standard + // specifies that these cases should open files 'as if by using fopen with + // "w"'. But adding that flag here will cause the unit test to leave files + // behind after running (which might or might not be an error in the unit + // test) so the matter needs further investigation before any changes are + // made. The old prstreams implementation used the non-standard flag + // ios::nocreate to control the use of PR_CREATE_FILE. + + if (flags == (ios_base::out)) { + prflags = PR_WRONLY | PR_TRUNCATE; + } else if (flags == (ios_base::out | ios_base::app)) { + prflags = PR_RDWR | PR_APPEND; + } else if (flags == (ios_base::out | ios_base::trunc)) { + prflags = PR_WRONLY | PR_TRUNCATE; + } else if (flags == (ios_base::in)) { + prflags = PR_RDONLY; + } else if (flags == (ios_base::in | ios_base::out)) { + prflags = PR_RDWR; + } else if (flags == (ios_base::in | ios_base::out | ios_base::trunc)) { + prflags = PR_RDWR | PR_TRUNCATE; + } else { + return NULL; // Unrecognized flag combination. + } + + if ((_fd = PR_Open(name, prflags, mode)) == NULL) { + return NULL; + } + + _opened = true; + + if (ate && + seekoff(0, ios_base::end, flags) == pos_type(traits_type::eof())) { + close(); + return NULL; + } + return this; } -PRfilebuf* -PRfilebuf::attach(PRFileDesc *fd) + +PRfilebuf *PRfilebuf::attach(PRFileDesc *fd) { - _opened = PR_FALSE; + if (_fd != NULL) { + return NULL; // Error if already open. + } + + _opened = false; _fd = fd; return this; } -int -PRfilebuf::overflow(int c) + +PRfilebuf *PRfilebuf::close() { - if (allocate()==EOF) // make sure there is a reserve area - return EOF; - if (PRfilebuf::sync()==EOF) // sync before new buffer created below - return EOF; + if (_fd == NULL) + return NULL; - if (!unbuffered()) - setp(base(),ebuf()); + int status = sync(); - if (c!=EOF){ - if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion - sputc(c); - else{ - if (PR_Write(_fd, &c, 1)!=1) - return(EOF); - } + if (PR_Close(_fd) == PR_FAILURE || + traits_type::eq_int_type(status, traits_type::eof())) { + return NULL; } - return(1); // return something other than EOF if successful -} -int -PRfilebuf::underflow() -{ - int count; - unsigned char tbuf; + _fd = NULL; + return this; +} - if (in_avail()) - return (int)(unsigned char) *gptr(); - if (allocate()==EOF) // make sure there is a reserve area - return EOF; - if (PRfilebuf::sync()==EOF) - return EOF; +streambuf *PRfilebuf::setbuf(char_type *ptr, streamsize len) +{ + if (is_open() && _buf_end) { + return NULL; + } - if (unbuffered()) - { - if (PR_Read(_fd,(void *)&tbuf,1)<=0) - return EOF; - return (int)tbuf; - } + if (!ptr || len <= 0) { + _unbuffered = true; + } else { + setb(ptr, ptr + len, false); + } - if ((count=PR_Read(_fd,(void *)base(),blen())) <= 0) - return EOF; // reached EOF - setg(base(),base(),base()+count); - return (int)(unsigned char) *gptr(); + return this; } -streambuf* -PRfilebuf::setbuf(char *buffptr, PRstreambuflen bufflen) + +streambuf::pos_type PRfilebuf::seekoff( + off_type offset, ios_base::seekdir dir, ios_base::openmode /*flags*/) { - if (is_open() && (ebuf())) - return 0; - if ((!buffptr) || (bufflen <= 0)) - unbuffered(1); - else - setb(buffptr, buffptr+bufflen, 0); - return this; -} + if (PR_GetDescType(_fd) != PR_DESC_FILE) { + return traits_type::eof(); + } -streampos -PRfilebuf::seekoff(streamoff offset, ios::seek_dir dir, int /* mode */) -{ - if (PR_GetDescType(_fd) == PR_DESC_FILE){ - PRSeekWhence fdir; - PRInt32 retpos; - switch (dir) { - case ios::beg : - fdir = PR_SEEK_SET; - break; - case ios::cur : - fdir = PR_SEEK_CUR; - break; - case ios::end : - fdir = PR_SEEK_END; - break; - default: - // error - return(EOF); - } + PRSeekWhence whence; + PRInt64 pos; + + switch (dir) { + case ios_base::beg: whence = PR_SEEK_SET; break; + case ios_base::cur: whence = PR_SEEK_CUR; break; + case ios_base::end: whence = PR_SEEK_END; break; + default: + return traits_type::eof(); // This should never happen. + } + + if (traits_type::eq_int_type(sync(), traits_type::eof())) { + return traits_type::eof(); + } - if (PRfilebuf::sync()==EOF) - return EOF; - if ((retpos=PR_Seek(_fd, offset, fdir))==-1L) - return (EOF); - return((streampos)retpos); - }else - return (EOF); + if ((pos = PR_Seek64(_fd, offset, whence)) == -1) { + return traits_type::eof(); + } + + return pos; } -int -PRfilebuf::sync() +int PRfilebuf::sync() { - PRInt32 count; - - if (_fd==0) - return(EOF); + if (_fd == NULL) { + return traits_type::eof(); + } - if (!unbuffered()){ - // Sync write area - if ((count=out_waiting())!=0){ + if (!_unbuffered) { + // Sync write area. + PRInt32 waiting; + if ((waiting = pptr() - pbase()) != 0) { PRInt32 nout; - if ((nout =PR_Write(_fd, - (void *) pbase(), - (unsigned int)count)) != count){ + if ((nout = PR_Write(_fd, pbase(), waiting)) != waiting) { if (nout > 0) { - // should set _pptr -= nout - pbump(-(int)nout); - memmove(pbase(), pbase()+nout, (int)(count-nout)); + // Should set _pptr -= nout. + pbump(-nout); + memmove(pbase(), pbase() + nout, waiting - nout); } - return(EOF); + return traits_type::eof(); } } - setp(0,0); // empty put area - - if (PR_GetDescType(_fd) == PR_DESC_FILE){ - // Sockets can't seek; don't need this - if ((count=in_avail()) > 0){ - if (PR_Seek(_fd, -count, PR_SEEK_CUR)!=-1L) - { - return (EOF); + setp(NULL, NULL); // Empty put area. + + if (PR_GetDescType(_fd) == PR_DESC_FILE) { + // Sockets can't seek; don't need this. + PROffset64 avail; + if ((avail = in_avail()) > 0) { + if (PR_Seek64(_fd, -avail, PR_SEEK_CUR) != -1) { + return traits_type::eof(); } } } - setg(0,0,0); // empty get area + setg(NULL, NULL, NULL); // Empty get area. } - return(0); + + return 0; } -PRfilebuf * -PRfilebuf::close() + +streambuf::int_type PRfilebuf::underflow() { - int retval; - if (_fd==0) - return 0; + PRInt32 count; + char_type byte; - retval = sync(); + if (gptr() != NULL && gptr() < egptr()) { + return traits_type::to_int_type(*gptr()); + } - if ((PR_Close(_fd)==0) || (retval==EOF)) - return 0; - _fd = 0; - return this; + // Make sure there is a reserve area. + if (!_unbuffered && _buf_base == NULL && !allocate()) { + return traits_type::eof(); + } + + // Sync before new buffer created below. + if (traits_type::eq_int_type(sync(), traits_type::eof())) { + return traits_type::eof(); + } + + if (_unbuffered) { + if (PR_Read(_fd, &byte, 1) <= 0) { + return traits_type::eof(); + } + + return traits_type::to_int_type(byte); + } + + if ((count = PR_Read(_fd, _buf_base, _buf_end - _buf_base)) <= 0) { + return traits_type::eof(); // Reached EOF. + } + + setg(_buf_base, _buf_base, _buf_base + count); + return traits_type::to_int_type(*gptr()); } -PRifstream::PRifstream(): -istream(new PRfilebuf) + +streambuf::int_type PRfilebuf::overflow(int_type c) { - _PRSTR_DELBUF(0); + // Make sure there is a reserve area. + if (!_unbuffered && _buf_base == NULL && !allocate()) { + return traits_type::eof(); + } + + // Sync before new buffer created below. + if (traits_type::eq_int_type(sync(), traits_type::eof())) { + return traits_type::eof(); + } + + if (!_unbuffered) { + setp(_buf_base, _buf_end); + } + + if (!traits_type::eq_int_type(c, traits_type::eof())) { + // Extract the byte to be written. + // (Required on big-endian architectures.) + char_type byte = traits_type::to_char_type(c); + if (!_unbuffered && pptr() < epptr()) { // Guard against recursion. + return sputc(byte); + } else { + if (PR_Write(_fd, &byte, 1) != 1) { + return traits_type::eof(); + } + } + } + + return traits_type::not_eof(c); } -PRifstream::PRifstream(PRFileDesc *fd): -istream(new PRfilebuf(fd)) + +bool PRfilebuf::allocate() { - _PRSTR_DELBUF(0); + char_type *buf = new(nothrow) char_type[BUFSIZ]; + if (buf == NULL) { + return false; + } + + setb(buf, buf + BUFSIZ, true); + return true; } -PRifstream::PRifstream(PRFileDesc *fd, char *buff, int bufflen): -istream(new PRfilebuf(fd, buff, bufflen)) + +void PRfilebuf::setb(char_type *buf_base, char_type *buf_end, bool user_buf) { - _PRSTR_DELBUF(0); + if (_buf_base && !_user_buf) { + delete[] _buf_base; + } + + _buf_base = buf_base; + _buf_end = buf_end; + _user_buf = user_buf; } -PRifstream::PRifstream(const char * name, int mode, int flags): -istream(new PRfilebuf) + +PRifstream::PRifstream(): + istream(NULL), + _filebuf() { - _PRSTR_DELBUF(0); - if (!rdbuf()->open(name, (mode|ios::in), flags)) - clear(rdstate() | ios::failbit); + init(&_filebuf); } -PRifstream::~PRifstream() + +PRifstream::PRifstream(PRFileDesc *fd): + istream(NULL), + _filebuf(fd) { - sync(); + init(&_filebuf); +} - delete rdbuf(); -#ifdef _PRSTR_BP - _PRSTR_BP = 0; -#endif + +PRifstream::PRifstream(PRFileDesc *fd, char_type *ptr, streamsize len): + istream(NULL), + _filebuf(fd, ptr, len) +{ + init(&_filebuf); } -streambuf * -PRifstream::setbuf(char * ptr, int len) + +PRifstream::PRifstream(const char *name, openmode flags, PRIntn mode): + istream(NULL), + _filebuf() { - if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){ - clear(rdstate() | ios::failbit); - return 0; + init(&_filebuf); + if (!_filebuf.open(name, flags | in, mode)) { + setstate(failbit); } - return rdbuf(); } -void -PRifstream::attach(PRFileDesc *fd) + +PRifstream::~PRifstream() { } + + +void PRifstream::open(const char *name, openmode flags, PRIntn mode) { - if (!(rdbuf()->attach(fd))) - clear(rdstate() | ios::failbit); + if (is_open() || !_filebuf.open(name, flags | in, mode)) { + setstate(failbit); + } } -void -PRifstream::open(const char * name, int mode, int flags) + +void PRifstream::attach(PRFileDesc *fd) { - if (is_open() || !(rdbuf()->open(name, (mode|ios::in), flags))) - clear(rdstate() | ios::failbit); + if (!_filebuf.attach(fd)) { + setstate(failbit); + } } -void -PRifstream::close() + +void PRifstream::close() { - clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit)); + if (_filebuf.close() == NULL) { + setstate(failbit); + } } + PRofstream::PRofstream(): -ostream(new PRfilebuf) + ostream(NULL), + _filebuf() { - _PRSTR_DELBUF(0); + init(&_filebuf); } + PRofstream::PRofstream(PRFileDesc *fd): -ostream(new PRfilebuf(fd)) + ostream(NULL), + _filebuf(fd) { - _PRSTR_DELBUF(0); + init(&_filebuf); } -PRofstream::PRofstream(PRFileDesc *fd, char *buff, int bufflen): -ostream(new PRfilebuf(fd, buff, bufflen)) + +PRofstream::PRofstream(PRFileDesc *fd, char_type *ptr, streamsize len): + ostream(NULL), + _filebuf(fd, ptr, len) { - _PRSTR_DELBUF(0); + init(&_filebuf); } -PRofstream::PRofstream(const char *name, int mode, int flags): -ostream(new PRfilebuf) + +PRofstream::PRofstream(const char *name, openmode flags, PRIntn mode): + ostream(NULL), + _filebuf() { - _PRSTR_DELBUF(0); - if (!rdbuf()->open(name, (mode|ios::out), flags)) - clear(rdstate() | ios::failbit); + init(&_filebuf); + if (!_filebuf.open(name, flags | out, mode)) { + setstate(failbit); + } } -PRofstream::~PRofstream() -{ - flush(); - delete rdbuf(); -#ifdef _PRSTR_BP - _PRSTR_BP = 0; -#endif -} +PRofstream::~PRofstream() { } + -streambuf * -PRofstream::setbuf(char * ptr, int len) +void PRofstream::open(const char *name, openmode flags, PRIntn mode) { - if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){ - clear(rdstate() | ios::failbit); - return 0; + if (is_open() || !_filebuf.open(name, flags | out, mode)) { + setstate(failbit); } - return rdbuf(); } -void -PRofstream::attach(PRFileDesc *fd) -{ - if (!(rdbuf()->attach(fd))) - clear(rdstate() | ios::failbit); -} -void -PRofstream::open(const char * name, int mode, int flags) +void PRofstream::attach(PRFileDesc *fd) { - if (is_open() || !(rdbuf()->open(name, (mode|ios::out), flags))) - clear(rdstate() | ios::failbit); + if (!_filebuf.attach(fd)) { + setstate(failbit); + } } -void -PRofstream::close() + +void PRofstream::close() { - clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit)); + if (_filebuf.close() == NULL) { + setstate(failbit); + } } + PRfstream::PRfstream(): -iostream(new PRfilebuf) + iostream(NULL), + _filebuf() { - _PRSTR_DELBUF_C(istream, 0); - _PRSTR_DELBUF_C(ostream, 0); + init(&_filebuf); } + PRfstream::PRfstream(PRFileDesc *fd): -iostream(new PRfilebuf(fd)) + iostream(NULL), + _filebuf(fd) { - _PRSTR_DELBUF_C(istream, 0); - _PRSTR_DELBUF_C(ostream, 0); + init(&_filebuf); } -PRfstream::PRfstream(PRFileDesc *fd, char *buff, int bufflen): -iostream(new PRfilebuf(fd, buff, bufflen)) + +PRfstream::PRfstream(PRFileDesc *fd, char_type *ptr, streamsize len): + iostream(NULL), + _filebuf(fd, ptr, len) { - _PRSTR_DELBUF_C(istream, 0); - _PRSTR_DELBUF_C(ostream, 0); + init(&_filebuf); } -PRfstream::PRfstream(const char *name, int mode, int flags): -iostream(new PRfilebuf) + +PRfstream::PRfstream(const char *name, openmode flags, PRIntn mode): + iostream(NULL), + _filebuf() { - _PRSTR_DELBUF_C(istream, 0); - _PRSTR_DELBUF_C(ostream, 0); - if (!rdbuf()->open(name, (mode|(ios::in|ios::out)), flags)) - clear(rdstate() | ios::failbit); + init(&_filebuf); + if (!_filebuf.open(name, flags | in | out, mode)) { + setstate(failbit); + } } -PRfstream::~PRfstream() -{ - sync(); - flush(); - delete rdbuf(); -#ifdef _PRSTR_BP - istream::_PRSTR_BP = 0; - ostream::_PRSTR_BP = 0; -#endif -} +PRfstream::~PRfstream() { } -streambuf * -PRfstream::setbuf(char * ptr, int len) + +void PRfstream::open(const char *name, openmode flags, PRIntn mode) { - if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){ - clear(rdstate() | ios::failbit); - return 0; + if (is_open() || !_filebuf.open(name, flags | in | out, mode)) { + setstate(failbit); } - return rdbuf(); } -void -PRfstream::attach(PRFileDesc *fd) -{ - if (!(rdbuf()->attach(fd))) - clear(rdstate() | ios::failbit); -} -void -PRfstream::open(const char * name, int mode, int flags) +void PRfstream::attach(PRFileDesc *fd) { - if (is_open() || !(rdbuf()->open(name, (mode|(ios::in|ios::out)), flags))) - clear(rdstate() | ios::failbit); + if (!_filebuf.attach(fd)) { + setstate(failbit); + } } -void -PRfstream::close() + +void PRfstream::close() { - clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit)); + if (_filebuf.close() == NULL) { + setstate(failbit); + } } - -#else - -// fix it sometime - -int fix_prfstreams () { return 0; } - -#endif |