This commit is contained in:
Glenn Maynard
2005-06-05 15:15:55 +00:00
parent 9dfc71554e
commit 162d235691
+59 -61
View File
@@ -31,21 +31,21 @@ static struct FileDriverEntry_DIR: public FileDriverEntry
class RageFileObjDirect: public RageFileObj class RageFileObjDirect: public RageFileObj
{ {
public: public:
RageFileObjDirect( const CString &path, int fd_, int mode_ ); RageFileObjDirect( const CString &sPath, int iFD, int iMode );
virtual ~RageFileObjDirect(); virtual ~RageFileObjDirect();
virtual int ReadInternal( void *pBuffer, size_t iBytes ); virtual int ReadInternal( void *pBuffer, size_t iBytes );
virtual int WriteInternal( const void *pBuffer, size_t iBytes ); virtual int WriteInternal( const void *pBuffer, size_t iBytes );
virtual int FlushInternal(); virtual int FlushInternal();
virtual int SeekInternal( int offset ); virtual int SeekInternal( int offset );
virtual RageFileBasic *Copy() const; virtual RageFileBasic *Copy() const;
virtual CString GetDisplayPath() const { return path; } virtual CString GetDisplayPath() const { return m_sPath; }
virtual int GetFileSize() const; virtual int GetFileSize() const;
private: private:
int fd; int m_iFD;
CString path; /* for Copy */ CString m_sPath; /* for Copy */
CString write_buf; CString m_sWriteBuf;
bool FinalFlush(); bool FinalFlush();
@@ -131,8 +131,7 @@ bool RageFileDriverDirect::Remove( const CString &path )
LOG->Trace("remove '%s'", (root + sPath).c_str()); LOG->Trace("remove '%s'", (root + sPath).c_str());
if( DoRemove( root + sPath ) == -1 ) if( DoRemove( root + sPath ) == -1 )
{ {
LOG->Warn("remove(%s) failed: %s", LOG->Warn( "remove(%s) failed: %s", (root + sPath).c_str(), strerror(errno) );
(root + sPath).c_str(), strerror(errno) );
return false; return false;
} }
FDB->DelFile( sPath ); FDB->DelFile( sPath );
@@ -142,8 +141,7 @@ bool RageFileDriverDirect::Remove( const CString &path )
LOG->Trace("rmdir '%s'", (root + sPath).c_str()); LOG->Trace("rmdir '%s'", (root + sPath).c_str());
if( DoRmdir( root + sPath ) == -1 ) if( DoRmdir( root + sPath ) == -1 )
{ {
LOG->Warn("rmdir(%s) failed: %s", LOG->Warn( "rmdir(%s) failed: %s", (root + sPath).c_str(), strerror(errno) );
(root + sPath).c_str(), strerror(errno) );
return false; return false;
} }
FDB->DelFile( sPath ); FDB->DelFile( sPath );
@@ -156,13 +154,13 @@ bool RageFileDriverDirect::Remove( const CString &path )
RageFileBasic *RageFileObjDirect::Copy() const RageFileBasic *RageFileObjDirect::Copy() const
{ {
int err; int iErr;
RageFileObj *ret = MakeFileObjDirect( path, m_iMode, err ); RageFileObj *ret = MakeFileObjDirect( m_sPath, m_iMode, iErr );
if( ret == NULL ) if( ret == NULL )
RageException::Throw("Couldn't reopen \"%s\": %s", path.c_str(), strerror(err) ); RageException::Throw( "Couldn't reopen \"%s\": %s", m_sPath.c_str(), strerror(iErr) );
ret->Seek( lseek( fd, 0, SEEK_CUR ) ); ret->Seek( lseek( m_iFD, 0, SEEK_CUR ) );
return ret; return ret;
} }
@@ -179,15 +177,15 @@ bool RageFileDriverDirect::Remount( const CString &sPath )
} }
static const unsigned int BUFSIZE = 1024*64; static const unsigned int BUFSIZE = 1024*64;
RageFileObjDirect::RageFileObjDirect( const CString &path_, int fd_, int mode_ ) RageFileObjDirect::RageFileObjDirect( const CString &sPath, int iFD, int iMode )
{ {
path = path_; m_sPath = sPath;
fd = fd_; m_iFD = iFD;
m_iMode = mode_; m_iMode = iMode;
ASSERT( fd != -1 ); ASSERT( m_iFD != -1 );
if( m_iMode & RageFile::WRITE ) if( m_iMode & RageFile::WRITE )
write_buf.reserve( BUFSIZE ); m_sWriteBuf.reserve( BUFSIZE );
} }
bool RageFileObjDirect::FinalFlush() bool RageFileObjDirect::FinalFlush()
@@ -204,26 +202,26 @@ bool RageFileObjDirect::FinalFlush()
return true; return true;
/* Force a kernel buffer flush. */ /* Force a kernel buffer flush. */
if( fsync( fd ) == -1 ) if( fsync( m_iFD ) == -1 )
{ {
LOG->Warn( "Error synchronizing %s: %s", this->path.c_str(), strerror(errno) ); LOG->Warn( "Error synchronizing %s: %s", this->m_sPath.c_str(), strerror(errno) );
SetError( strerror(errno) ); SetError( strerror(errno) );
return false; return false;
} }
#if !defined(WIN32) #if !defined(WIN32)
/* Wait for the directory to be flushed. */ /* Wait for the directory to be flushed. */
int dirfd = open( Dirname(path), O_RDONLY ); int dirfd = open( Dirname(m_sPath), O_RDONLY );
if( dirfd == -1 ) if( dirfd == -1 )
{ {
LOG->Warn( "Error synchronizing open(%s dir): %s", this->path.c_str(), strerror(errno) ); LOG->Warn( "Error synchronizing open(%s dir): %s", this->m_sPath.c_str(), strerror(errno) );
SetError( strerror(errno) ); SetError( strerror(errno) );
return false; return false;
} }
if( fsync( dirfd ) == -1 ) if( fsync( dirfd ) == -1 )
{ {
LOG->Warn( "Error synchronizing fsync(%s dir): %s", this->path.c_str(), strerror(errno) ); LOG->Warn( "Error synchronizing fsync(%s dir): %s", this->m_sPath.c_str(), strerror(errno) );
SetError( strerror(errno) ); SetError( strerror(errno) );
close( dirfd ); close( dirfd );
return false; return false;
@@ -239,11 +237,11 @@ RageFileObjDirect::~RageFileObjDirect()
{ {
bool failed = !FinalFlush(); bool failed = !FinalFlush();
if( fd != -1 ) if( m_iFD != -1 )
{ {
if( close( fd ) == -1 ) if( close( m_iFD ) == -1 )
{ {
LOG->Warn("Error closing %s: %s", this->path.c_str(), strerror(errno) ); LOG->Warn( "Error closing %s: %s", this->m_sPath.c_str(), strerror(errno) );
SetError( strerror(errno) ); SetError( strerror(errno) );
failed = true; failed = true;
} }
@@ -255,7 +253,7 @@ RageFileObjDirect::~RageFileObjDirect()
!(m_iMode & RageFile::STREAMED) ) !(m_iMode & RageFile::STREAMED) )
{ {
/* /*
* We now have path written to MakeTempFilename(path). Rename the temporary * We now have path written to MakeTempFilename(m_sPath). Rename the temporary
* file over the real path. This should be an atomic operation with a journalling * file over the real path. This should be an atomic operation with a journalling
* filesystem. That is, there should be no intermediate state a JFS might restore * filesystem. That is, there should be no intermediate state a JFS might restore
* the file we're writing (in the case of a crash/powerdown) to an empty or partial * the file we're writing (in the case of a crash/powerdown) to an empty or partial
@@ -269,8 +267,8 @@ RageFileObjDirect::~RageFileObjDirect()
* A safer (but much slower) way to do this is to simply CopyFile a backup first. * A safer (but much slower) way to do this is to simply CopyFile a backup first.
*/ */
CString sOldPath = MakeTempFilename(path); CString sOldPath = MakeTempFilename(m_sPath);
CString sNewPath = path; CString sNewPath = m_sPath;
#if defined(WIN32) #if defined(WIN32)
if( WinMoveFile(sOldPath, sNewPath) ) if( WinMoveFile(sOldPath, sNewPath) )
@@ -292,25 +290,25 @@ RageFileObjDirect::~RageFileObjDirect()
} }
} }
int RageFileObjDirect::ReadInternal( void *buf, size_t bytes ) int RageFileObjDirect::ReadInternal( void *pBuf, size_t iBytes )
{ {
int ret = read( fd, buf, bytes ); int iRet = read( m_iFD, pBuf, iBytes );
if( ret == -1 ) if( iRet == -1 )
{ {
SetError( strerror(errno) ); SetError( strerror(errno) );
return -1; return -1;
} }
return ret; return iRet;
} }
/* write(), but retry a couple times on EINTR. */ /* write(), but retry a couple times on EINTR. */
static int retried_write( int fd, const void *buf, size_t count ) static int retried_write( int iFD, const void *pBuf, size_t iCount )
{ {
int tries = 3, ret; int tries = 3, ret;
do do
{ {
ret = write( fd, buf, count ); ret = write( iFD, pBuf, iCount );
} }
while( ret == -1 && errno == EINTR && tries-- ); while( ret == -1 && errno == EINTR && tries-- );
@@ -320,61 +318,61 @@ static int retried_write( int fd, const void *buf, size_t count )
int RageFileObjDirect::FlushInternal() int RageFileObjDirect::FlushInternal()
{ {
if( !write_buf.size() ) if( !m_sWriteBuf.size() )
return 0; return 0;
int ret = retried_write( fd, write_buf.data(), write_buf.size() ); int iRet = retried_write( m_iFD, m_sWriteBuf.data(), m_sWriteBuf.size() );
if( ret == -1 ) if( iRet == -1 )
{ {
LOG->Warn("Error writing %s: %s", this->path.c_str(), strerror(errno) ); LOG->Warn("Error writing %s: %s", this->m_sPath.c_str(), strerror(errno) );
SetError( strerror(errno) ); SetError( strerror(errno) );
} }
write_buf.erase(); m_sWriteBuf.erase();
write_buf.reserve( BUFSIZE ); m_sWriteBuf.reserve( BUFSIZE );
return ret; return iRet;
} }
int RageFileObjDirect::WriteInternal( const void *buf, size_t bytes ) int RageFileObjDirect::WriteInternal( const void *pBuf, size_t iBytes )
{ {
if( write_buf.size()+bytes > BUFSIZE ) if( m_sWriteBuf.size()+iBytes > BUFSIZE )
{ {
if( Flush() == -1 ) if( Flush() == -1 )
return -1; return -1;
ASSERT( !write_buf.size() ); ASSERT( !m_sWriteBuf.size() );
/* The buffer is cleared. If we still don't have space, it's bigger than /* The buffer is cleared. If we still don't have space, it's bigger than
* the buffer size, so just write it directly. */ * the buffer size, so just write it directly. */
if( bytes >= BUFSIZE ) if( iBytes >= BUFSIZE )
{ {
int ret = retried_write( fd, buf, bytes ); int iRet = retried_write( m_iFD, pBuf, iBytes );
if( ret == -1 ) if( iRet == -1 )
{ {
LOG->Warn("Error writing %s: %s", this->path.c_str(), strerror(errno) ); LOG->Warn("Error writing %s: %s", this->m_sPath.c_str(), strerror(errno) );
SetError( strerror(errno) ); SetError( strerror(errno) );
return -1; return -1;
} }
return bytes; return iBytes;
} }
} }
write_buf.append( (const char *)buf, (const char *)buf+bytes ); m_sWriteBuf.append( (const char *) pBuf, (const char *) pBuf+iBytes );
return bytes; return iBytes;
} }
int RageFileObjDirect::SeekInternal( int offset ) int RageFileObjDirect::SeekInternal( int iOffset )
{ {
return lseek( fd, offset, SEEK_SET ); return lseek( m_iFD, iOffset, SEEK_SET );
} }
int RageFileObjDirect::GetFileSize() const int RageFileObjDirect::GetFileSize() const
{ {
const int OldPos = lseek( fd, 0, SEEK_CUR ); const int iOldPos = lseek( m_iFD, 0, SEEK_CUR );
ASSERT_M( OldPos != -1, strerror(errno) ); ASSERT_M( iOldPos != -1, strerror(errno) );
const int ret = lseek( fd, 0, SEEK_END ); const int iRet = lseek( m_iFD, 0, SEEK_END );
ASSERT_M( ret != -1, strerror(errno) ); ASSERT_M( iRet != -1, strerror(errno) );
lseek( fd, OldPos, SEEK_SET ); lseek( m_iFD, iOldPos, SEEK_SET );
return ret; return iRet;
} }
/* /*