Logo Search packages:      
Sourcecode: u++ version File versions

uFile.cc

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Peter A. Buhr 1994
// 
// uFile.cc -- 
// 
// Author           : Peter Buhr
// Created On       : Tue Mar 29 16:42:36 1994
// Last Modified By : Peter A. Buhr
// Last Modified On : Wed Aug 11 14:11:49 2004
// Update Count     : 279
//
// This  library is free  software; you  can redistribute  it and/or  modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
// option) any later version.
// 
// This library is distributed in the  hope that it will be useful, but WITHOUT
// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
// for more details.
// 
// You should  have received a  copy of the  GNU Lesser General  Public License
// along  with this library.
// 


#define __U_KERNEL__
#include <uC++.h>
#include <uFile.h>
#include <uSocket.h>

//#include <uDebug.h>

#include <cstring>                              // strerror
#include <unistd.h>                             // read, write, close, etc.
#if defined( __linux__ )
#include <sys/uio.h>                            // readv, writev
#endif // __linux__


//######################### uFile #########################


void uFile::access() {
    accessCnt += 1;
} // uFile::access

void uFile::unaccess() {
    accessCnt -= 1;
} // uFile::unaccess

void uFile::uCreateFile( const char *name ) {
    uName = new char[strlen( name ) + 1];
    strcpy( uName, name );
    accessCnt = 0;
} // uFile::uCreateFile

uFile::uFile( const char *name ) {
    uCreateFile( name );
} // uFile::uFile

uFile::~uFile() {
    uTerminateFailure temp( *this, accessCnt, "terminating access with outstanding accessor(s)" );
    if ( uName != 0 ) delete uName;             // safe to delete name as the name is copied in the exception object
    if ( accessCnt != 0 ) {
      if ( ! std::uncaught_exception() ) uThrow temp;
    } // if
} // uFile::~uFile

const char *uFile::uGetName() const {
    return
#ifdef __U_DEBUG__
      ( uName == NULL || uName == (const char *)-1 ) ? "*unknown*" : // storage might be scrubbed
#endif // __U_DEBUG__
      uName;
} // uFile::uGetName

void uFile::status( struct stat &buf ) {
    int code;

    for ( ;; ) {
      code = ::stat( uName, &buf );
      if ( code != -1 ) break;
      if ( errno != EINTR ) break;              // timer interrupt ?
    } // for
    if ( code == -1 ) {
      uRaise uFile::uStatusFailure( *this, buf, "could not obtain statistical information for file" );
    } // if
} // uFile::status


//######################### uFileIO #########################


uFileIO::uFileIO( uIOaccess &acc ) : access( acc ) {
} // uFileIO::uFileIO

uFileIO::~uFileIO() {
} // uFileIO::~uFileIO

int uFileIO::_read( char *buf, int len ) {
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uSetPollFlag( access.fd );
    int rlen = ::read( access.fd, buf, len );
    int terrno = errno;                         // preserve errno across calls
#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p._read attempting read to fd:%d, rlen:%d, errno:%d\n", this, access.fd, rlen, errno );
#endif // __U_DEBUG_H__
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uClearPollFlag( access.fd );
    errno = terrno;
    return rlen;
} // uFileIO::_read

int uFileIO::_readv( const struct iovec *iov, int iovcnt ) {
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uSetPollFlag( access.fd );
    int rlen = ::readv( access.fd,
#ifdef __osf__
                  (struct iovec *)        // TEMPORARY: missing "const"
#endif // __osf__
                  iov, iovcnt );
    int terrno = errno;                         // preserve errno across calls
#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p._readv attempting readv to fd:%d, rlen:%d, errno:%d\n", this, access.fd, rlen, errno );
#endif // __U_DEBUG_H__
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uClearPollFlag( access.fd );
    errno = terrno;
    return rlen;
} // uFileIO::_readv

int uFileIO::_write( char *buf, int len ) {
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uSetPollFlag( access.fd );
    int wlen = ::write( access.fd, buf, len );
    int terrno = errno;                         // preserve errno across calls
#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p._write attempting write to fd:%d, wlen:%d, errno:%d\n", this, access.fd, wlen, errno );
#endif // __U_DEBUG_H__
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uClearPollFlag( access.fd );
    errno = terrno;
    return wlen;
} // uFileIO::_write

int uFileIO::_writev( const struct iovec *iov, int iovcnt ) {
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uSetPollFlag( access.fd );
    int wlen = ::writev( access.fd,
#ifdef __osf__
                  (struct iovec *)        // TEMPORARY: missing "const"
#endif // __osf__
                   iov, iovcnt );
    int terrno = errno;                         // preserve errno across calls
#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p._writev attempting writev to fd:%d, wlen:%d, errno:%d\n", this, access.fd, wlen, errno );
#endif // __U_DEBUG_H__
    if ( access.poll.uGetStatus() == uPoll::uPollOnDemand ) access.poll.uClearPollFlag( access.fd );
    errno = terrno;
    return wlen;
} // uFileIO::_writev

int uFileIO::read( char *buf, int len, uDuration *timeout ) {
    int rlen;

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.read attempting read to fd:%d\n", this, access.fd );
#endif // __U_DEBUG_H__

    for ( ;; ) {
      rlen = _read( buf, len );
      if ( rlen != -1 ) break;
      if ( ! ( errno == EINTR || errno == U_EWOULDBLOCK ) ) break;
      if ( errno == U_EWOULDBLOCK ) {
          int mask = uCluster::uReadSelect;
          if ( timeout == NULL ) {
            uThisCluster().uSelect( access.fd, mask );
          } else {
            timeval t = *timeout;               // convert to timeval for select
            if ( uThisCluster().uSelect( access.fd, mask, &t ) == 0 ) { // timeout ?
                // determine derived type using C++ idiom
                if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
                  uThrow uFileAccess::uReadTimeout( *fa, buf, len, timeout, "timeout during file read" );
                } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
                  uThrow uSocketAccept::uReadTimeout( *sa, buf, len, 0, NULL, 0, timeout, "timeout during socket read" );
                } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
                  uThrow uSocketClient::uReadTimeout( *sc, buf, len, 0, NULL, 0, timeout, "timeout during socket read" );
                } else {
                  uAbort( "(uFileIO &)0x%p.read : internal error, invalid runtime type", this );
                } // if
            } // if
          } // if
      } // if
    } // for    

    if ( rlen == -1 ) {
      if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
          uThrow uFileAccess::uReadFailure( *fa, buf, len, timeout, "file read fails" );
      } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
          uThrow uSocketAccept::uReadFailure( *sa, buf, len, 0, NULL, 0, timeout, "socket read fails" );
      } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
          uThrow uSocketClient::uReadFailure( *sc, buf, len, 0, NULL, 0, timeout, "socket read fails" );
      } else {
          uAbort( "(uFileIO &)0x%p.read : internal error, invalid runtime type", this );
      } // if
    } // if

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.read completed read to fd:%d, read:%d bytes\n", this, access.fd, rlen );
#endif // __U_DEBUG_H__
    return rlen;
} // uFileIO::read

int uFileIO::readv( const struct iovec *iov, int iovcnt, uDuration *timeout ) {
    int rlen;

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.readv attempting read to fd:%d\n", this, access.fd );
#endif // __U_DEBUG_H__

    for ( ;; ) {
      rlen = _readv( iov, iovcnt );
      if ( rlen != -1 ) break;
      if ( ! ( errno == EINTR || errno == U_EWOULDBLOCK ) ) break;
      if ( errno == U_EWOULDBLOCK ) {
          int mask = uCluster::uReadSelect;
          if ( timeout == NULL ) {
            uThisCluster().uSelect( access.fd, mask );
          } else {
            timeval t = *timeout;               // convert to timeval for select
            if ( uThisCluster().uSelect( access.fd, mask, &t ) == 0 ) { // timeout ?
                // determine derived type using C++ idiom
                if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
                  uThrow uFileAccess::uReadTimeout( *fa, (const char *)iov, iovcnt, timeout, "timeout during file readv" );
                } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
                  uThrow uSocketAccept::uReadTimeout( *sa, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "timeout during socket readv" );
                } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
                  uThrow uSocketClient::uReadTimeout( *sc, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "timeout during socket readv" );
                } else {
                  uAbort( "(uFileIO &)0x%p.readv : internal error, invalid runtime type", this );
                } // if
            } // if
          } // if
      } // if
    } // for    
    if ( rlen == -1 ) {
      if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
          uThrow uFileAccess::uReadFailure( *fa, (const char *)iov, iovcnt, timeout, "file readv fails" );
      } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
          uThrow uSocketAccept::uReadFailure( *sa, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "socket readv fails" );
      } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
          uThrow uSocketClient::uReadFailure( *sc, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "socket readv fails" );
      } else {
          uAbort( "(uFileIO &)0x%p.readv : internal error, invalid runtime type", this );
      } // if
    } // if

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.readv completed read to fd:%d, read:%d bytes\n", this, access.fd, rlen );
#endif // __U_DEBUG_H__
    return rlen;
} // uFileIO::readv

int uFileIO::write( char *buf, int len, uDuration *timeout ) {
    int count, wlen;

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.write attempting write to fd:%d\n", this, access.fd );
#endif // __U_DEBUG_H__

    for ( count = 0; count < len; count += wlen ) {   // ensure all data is written
      for ( ;; ) {
          wlen = _write( buf + count, len - count );
        if ( wlen != -1 ) break;
        if ( ! ( errno == EINTR || errno == U_EWOULDBLOCK ) ) break;
          if ( errno == U_EWOULDBLOCK ) {
            int mask = uCluster::uWriteSelect;
            if ( timeout == NULL ) {
                uThisCluster().uSelect( access.fd, mask );
            } else {
                timeval t = *timeout;           // convert to timeval for select
                if ( uThisCluster().uSelect( access.fd, mask, &t ) == 0 ) { // timeout ?
                  if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
                      uThrow uFileAccess::uWriteTimeout( *fa, buf, len, timeout, "timeout during file write" );
                  } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
                      uThrow uSocketAccept::uWriteTimeout( *sa, buf, len, 0, NULL, 0, timeout, "timeout during socket write" );
                  } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
                      uThrow uSocketClient::uWriteTimeout( *sc, buf, len, 0, NULL, 0, timeout, "timeout during socket write" );
                  } else {
                      uAbort( "(uFileIO &)0x%p.write : internal error, invalid runtime type", this );
                  } // if
                } // if
            } // if
          } // if
      } // for

      if ( wlen == -1 ) {
          // EIO means the write is to stdout but the shell has terminated (I
          // think). Normally, people want this to work as if stdout is
          // magically redirected to /dev/null, instead of aborting the
          // program.

      if ( errno == EIO ) break;

          if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
            uThrow uFileAccess::uWriteFailure( *fa, buf, len, timeout, "file write fails" );
          } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
            uThrow uSocketAccept::uWriteFailure( *sa, buf, len, 0, NULL, 0, timeout, "socket write fails" );
          } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
            uThrow uSocketClient::uWriteFailure( *sc, buf, len, 0, NULL, 0, timeout, "socket write fails" );
          } else {
            uAbort( "(uFileIO &)0x%p.write : internal error, invalid runtime type", this );
          } // if
      } // if
    } // for

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.write completed write to fd:%d, wrote:%d bytes\n", this, access.fd, len );
#endif // __U_DEBUG_H__
    return len;                                 // always return the specified length
} // uFileIO::write

int uFileIO::writev( const struct iovec *iov, int iovcnt, uDuration *timeout ) {
    int wlen;

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.writev attempting write to fd:%d\n", this, access.fd );
#endif // __U_DEBUG_H__

    for ( ;; ) {
      wlen = _writev( iov, iovcnt );
      if ( wlen != -1 ) break;
      if ( ! ( errno == EINTR || errno == U_EWOULDBLOCK ) ) break;
      if ( errno == U_EWOULDBLOCK ) {
          int mask = uCluster::uWriteSelect;
          if ( timeout == NULL ) {
            uThisCluster().uSelect( access.fd, mask );
          } else {
            timeval t = *timeout;         // convert to timeval for select
            if ( uThisCluster().uSelect( access.fd, mask, &t ) == 0 ) { // timeout ?
                if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
                  uThrow uFileAccess::uWriteTimeout( *fa, (const char *)iov, iovcnt, timeout, "timeout during file writev" );
                } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
                  uThrow uSocketAccept::uWriteTimeout( *sa, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "timeout during socket writev" );
                } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
                  uThrow uSocketClient::uWriteTimeout( *sc, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "timeout during socket writev" );
                } else {
                  uAbort( "(uFileIO &)0x%p.writev : internal error, invalid runtime type", this );
                } // if
            } // if
          } // if
      } // if
    } // for

    // EIO means the write is to stdout but the shell has terminated (I
    // think). Normally, people want this to work as if stdout is magically
    // redirected to /dev/null, instead of aborting the program.

    if ( wlen == -1 && errno != EIO ) {
      if ( uFileAccess *fa = dynamic_cast<uFileAccess *>(this) ) {
          uThrow uFileAccess::uWriteFailure( *fa, (const char *)iov, iovcnt, timeout, "file writev fails" );
      } else if ( uSocketAccept *sa = dynamic_cast<uSocketAccept *>(this) ) {
          uThrow uSocketAccept::uWriteFailure( *sa, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "socket writev fails" );
      } else if ( uSocketClient *sc = dynamic_cast<uSocketClient *>(this) ) {
          uThrow uSocketClient::uWriteFailure( *sc, (const char *)iov, iovcnt, 0, NULL, 0, timeout, "socket writev fails" );
      } else {
          uAbort( "(uFileIO &)0x%p.writev : internal error, invalid runtime type", this );
      } // if
    } // if

#ifdef __U_DEBUG_H__
    uDebugPrt( "(uFileIO &)0x%p.writev completed write to fd:%d, wrote:%d bytes\n", this, access.fd, wlen );
#endif // __U_DEBUG_H__
    return wlen;
} // uFileIO::writev


int uFileIO::fd() {
    return access.fd;
} // uFileIO::fd


//######################### uFileAccess #########################


uFileAccess::uFileAccess( int fd, uFile &f ) : uFileIO( access ), ufile( f ) {
    access.fd = fd;
    access.poll.uSetStatus( uPoll::uPollOnDemand );
    ufile.access();
} // uFileAccess::uFileAccess

uFileAccess::uFileAccess( uFile &f, int flags, int mode ) : uFileIO( access ), ufile( f ) {
    for ( ;; ) {
      access.fd = ::open( ufile.uName, flags, mode );
      if ( access.fd != -1 ) break;
      if ( errno != EINTR ) break;              // timer interrupt ?
    } // for
    if ( access.fd == -1 ) {
        uThrow uFileAccess::uOpenFailure( *this, flags, mode, "unable to access file" );
    } // if
    access.poll.uComputeStatus( access.fd );
    if ( access.poll.uGetStatus() == uPoll::uAlwaysPoll ) access.poll.uSetPollFlag( access.fd );
    ufile.access();
} // uFileAccess::uFileAccess

uFileAccess::~uFileAccess() {
    ufile.unaccess();
    if ( access.poll.uGetStatus() == uPoll::uAlwaysPoll ) access.poll.uClearPollFlag( access.fd );
    if ( access.fd >= 3 ) {                     // don't close the standard file descriptors
      int code;

      uThisCluster().uCloseFD( access.fd );
      for ( ;; ) {
          code = ::close( access.fd );
        if ( code != -1 ) break;
        if ( errno != EINTR ) break;                  // timer interrupt ?
      } // for
      if ( code == -1 ) {
          if ( ! std::uncaught_exception() ) uRaise uFileAccess::uCloseFailure( *this, "unable to terminate access to file" );
      } // if
    } // if
} // uFileAccess::~uFileAccess

off_t uFileAccess::lseek( off_t offset, int whence ) {
    off_t code;

    for ( ;; ) {
      code = ::lseek( access.fd, offset, whence );
      if ( code != -1 ) break;
      if ( errno != EINTR ) break;              // timer interrupt ?
    } // for
    if ( code == -1 ) {
        uThrow uFileAccess::uSeekFailure( *this, offset, whence, "could not seek file" );
    } // if
    return code;
} // uFileAccess::lseek

int uFileAccess::fsync() {
    int code;

    for ( ;; ) {
      code = ::fsync( access.fd );
      if ( code != -1 ) break;
      if ( errno != EINTR ) break;              // timer interrupt ?
    } // for
    if ( code == -1 ) {
        uThrow uFileAccess::uSyncFailure( *this, "could not fsync file" );
    } // if
    return code;
} // uFileAccess::fsync


//######################### uFile (cont) #########################


uFile::uFailure::uFailure( const uFile &f, const char *const msg ) : uIOFailure( msg ), f( f ) {
    // file name is copied because its storage can be freed and scrubbed before handler starts
    strncpy( uName, f.uGetName(), uEHMMaxName );
    if ( strlen( f.uGetName() ) > uEHMMaxName ) {     // name too long ?
      strcpy( &uName[uEHMMaxName], "..." );           // add 4 character ...
    } // if
} // uFile::uFailure::uFailure

uFile::uFailure::~uFailure() {}

const uFile &uFile::uFailure::file() const { return f; }

const char *uFile::uFailure::uGetName() const { return uName; }

void uFile::uFailure::defaultTerminate() const {
    uAbort( "(uFile &)0x%p, %.256s \"%.256s\".", &file(), message(), uGetName() );
} // uFile::uFailure::defaultTerminate


uFile::uTerminateFailure::uTerminateFailure( const uFile &f, const int accessCnt, const char *const msg ) :
      uFile::uFailure( f, msg ), accessCnt( accessCnt ) {}

void uFile::uTerminateFailure::defaultTerminate() const {
    uAbort( "(uFile &)0x%p.~uFile(), %.256s, %d accessor(s) outstanding.", &file(), message(), accessCnt );
} // uFile::uTerminateFailure::defaultTerminate


uFile::uStatusFailure::uStatusFailure( const uFile &f, const struct stat &buf, const char *const msg ) : uFile::uFailure( f, msg ), buf( buf ) {}

void uFile::uStatusFailure::defaultTerminate() const {
    uAbort( "(uFile &)0x%p.status( buf:0x%p ), %.256s \"%.256s\".\nError(%d) : %s.",
          &file(), &buf, message(), uGetName(), errNo(), strerror( errNo() ) );
} // uFile::uStatusFailure::defaultTerminate


uInitEvent(uFile::uFailure);
uInitEvent(uFile::uTerminateFailure);
uInitEvent(uFile::uStatusFailure);


//######################### uFileAccess (cont) #########################


uFileAccess::uFailure::uFailure( const uFileAccess &fa, const char *const msg ) : uFile::uFailure( fa.ufile, msg ), fa( fa ) {
    fd = fa.access.fd;
} // uFileAccess::uFailure::uFailure

const uFileAccess &uFileAccess::uFailure::fileAccess() const {
    return fa;
} // uFileAccess::uFailure::fileAccess

int uFileAccess::uFailure::fileDescriptor() const {
    return fd;
} // uFileAccess::uFailure::fileDescriptor

void uFileAccess::uFailure::defaultTerminate() const {
    uAbort( "(uFileAccess &)0x%p( file:0x%p ), %.256s file \"%.256s\".",
          &fileAccess(), &file(), message(), uGetName() );
} // uFileAccess::uFailure::defaultTerminate


uFileAccess::uOpenFailure::uOpenFailure( uFileAccess &fa, int flags, int mode, const char *const msg ) :
      uFileAccess::uFailure( fa, msg ), flags( flags ), mode( mode ) {}

void uFileAccess::uOpenFailure::defaultTerminate() const {
    uAbort( "(uFileAccess &)0x%p.uFileAccess( file:0x%p, flags:0x%x, mode:0x%x ), %.256s \"%.256s\".\nError(%d) : %s.",
          &fileAccess(), &file(), flags, mode, message(), uGetName(), errNo(), strerror( errNo() ) );
} // uFile::uOpenFailure::defaultTerminate


uFileAccess::uCloseFailure::uCloseFailure( uFileAccess &fa, const char *const msg ) : uFileAccess::uFailure( fa, msg ) {}

void uFileAccess::uCloseFailure::defaultTerminate() const {
    uAbort( "(uFileAccess &)0x%p.~uFileAccess(), %.256s \"%.256s\".\nError(%d) : %s.",
          &fileAccess(), message(), uGetName(), errNo(), strerror( errNo() ) );
} // uFile::uCloseFailure::defaultTerminate


uFileAccess::uSeekFailure::uSeekFailure( const uFileAccess &fa, const off_t offset, const int whence, const char *const msg ) :
      uFileAccess::uFailure( fa, msg ), offset( offset ), whence( whence ) {}

void uFileAccess::uSeekFailure::defaultTerminate() const {
    uAbort( "(uFile &)0x%p.lseek( offset:%ld, whence:%d ), %.256s file \"%.256s\".\nError(%d) : %s.",
          &file(), (long int)offset, whence, message(), uGetName(), errNo(), strerror( errNo() ) );
} // uFileAccess::uSeekFailure::defaultTerminate


uFileAccess::uSyncFailure::uSyncFailure( const uFileAccess &fa, const char *const msg ) : uFileAccess::uFailure( fa, msg ) {}

void uFileAccess::uSyncFailure::defaultTerminate() const {
    uAbort( "(uFileAccess &)0x%p.fsync(), %.256s \"%.256s\".\nError(%d) : %s.",
          &file(), message(), uGetName(), errNo(), strerror( errNo() ) );
} // uFileAccess::uSyncFailure::defaultTerminate


void uFileAccess::uWriteFailure::defaultResume() const {
    if ( errNo() != EIO ) {
      uThrow *this;
    } // if
} // uFileAccess::uWriteFailure::defaultResume


uFileAccess::uReadFailure::uReadFailure( const uFileAccess &fa, const char *buf, const int len, const uDuration *timeout, const char *const msg ) :
      uFileAccess::uFailure( fa, msg ), buf( buf ), len( len ), timeout( timeout ) {}

void uFileAccess::uReadFailure::defaultTerminate() const {
    uAbort( "(uFileAccess &)0x%p.read( buf:0x%p, len:%d, timeout:0x%p ) : %.256s for file descriptor %d.\nError(%d) : %s.",
          &fileAccess(), buf, len, timeout, message(), fileDescriptor(), errNo(), strerror( errNo() ) );
} // uFileAccess::uReadFailure::defaultTerminate

uFileAccess::uReadTimeout::uReadTimeout( const uFileAccess &fa, const char *buf, const int len, const uDuration *timeout, const char *const msg ) :
      uFileAccess::uReadFailure( fa, buf, len, timeout, msg ) {}


uFileAccess::uWriteFailure::uWriteFailure( const uFileAccess &fa, const char *buf, const int len, const uDuration *timeout, const char *const msg ) :
      uFileAccess::uFailure( fa, msg ), buf( buf ), len( len ), timeout( timeout ) {}

void uFileAccess::uWriteFailure::defaultTerminate() const {
    uAbort( "(uFileAccess &)0x%p.write( buf:0x%p, len:%d, timeout:0x%p ) : %.256s for file descriptor %d.\nError(%d) : %s.",
          &fileAccess(), buf, len, timeout, message(), fileDescriptor(), errNo(), strerror( errNo() ) );
} // uFileAccess::uWriteFailure::defaultTerminate

uFileAccess::uWriteTimeout::uWriteTimeout( const uFileAccess &fa, const char *buf, const int len, const uDuration *timeout, const char *const msg ) :
      uFileAccess::uWriteFailure( fa, buf, len, timeout, msg ) {}


uInitEvent(uFileAccess::uFailure);
uInitEvent(uFileAccess::uOpenFailure);
uInitEvent(uFileAccess::uCloseFailure);
uInitEvent(uFileAccess::uSyncFailure);
uInitEvent(uFileAccess::uSeekFailure);
uInitEvent(uFileAccess::uReadFailure);
uInitEvent(uFileAccess::uReadTimeout);
uInitEvent(uFileAccess::uWriteFailure);
uInitEvent(uFileAccess::uWriteTimeout);


// Local Variables: //
// compile-command: "gmake install" //
// End: //

Generated by  Doxygen 1.6.0   Back to index