392 lines
12 KiB
C++
392 lines
12 KiB
C++
/*
|
|
* Copyright 1995, 1996 Perforce Software. All rights reserved.
|
|
*
|
|
* This file is part of Perforce - the FAST SCM System.
|
|
*/
|
|
|
|
/*
|
|
* FileSys.h - OS specific file manipulation
|
|
*
|
|
* Public classes:
|
|
*
|
|
* FileSys - a file handle, with all the trimmings
|
|
*
|
|
* Static Public methods:
|
|
*
|
|
* FileSys::Create() - create a FileSys, given its file type
|
|
* FileSys::CreateTemp() - create, destructor deletes the file
|
|
* FileSys::CreateGloablTemp() - Temp, constructor makes a global name
|
|
* FileSys::FileExists() - does the passed filepath exist in the file system
|
|
* FileSys::Perm() - translate string perm to enum
|
|
*
|
|
* Public methods:
|
|
*
|
|
* FileSys::Set() - set file name
|
|
* FileSys::Name() - get file name
|
|
* FileSys::GetType() - get type previously set
|
|
* FileSys::IsTextual() - return if type is one of text types
|
|
* FileSys::IsExec() - return if type indicates executable bit set
|
|
* FileSys::DoIndirectWrites() - updates should write temp/rename
|
|
*
|
|
* FileSys::MakeGlobalTemp() - make a temp name in a global directory
|
|
* FileSys::MakeLocalTemp() - make a temp name in same dir as file
|
|
*
|
|
* FileSys::IsDeleteOnClose() - will file be removed on close?
|
|
* FileSys::SetDeleteOnClose() - file will be removed
|
|
* FileSys::ClearDeleteOnClose() - file won't be removed
|
|
*
|
|
* FileSys::Perms() - set file permission for close after write
|
|
* FileSys::ModTime() - set mod time for close after write
|
|
* FileSys::ChmodTime() - use modTime value to change mod time directly
|
|
*
|
|
* FileSys::Open() - open named file according to mode
|
|
* FileSys::Write() - write a block into file
|
|
* FileSys::Read() - read a block from file
|
|
* FileSys::Readlink() - NOT IMPL ON WINDOWS returns target of the symbolic link
|
|
* FileSys::ReadLine() - read a line into string
|
|
* FileSys::ReadWhole() - read whole file into string
|
|
* FileSys::Close() - close file description
|
|
*
|
|
* FileSys::Stat() - return flags if file exists, writable
|
|
* FileSys::Truncate() - set file to zero length if it exists
|
|
* FileSys::Unlink() - remove single file
|
|
*
|
|
* FileSys::GetFd() - return underlying int fd, FST_BINARY only
|
|
* FileSys::GetSize() - return file size, FST_BINARY,TEXT,ATEXT only
|
|
* FileSys::GetOwner() - return the UID of the file owner
|
|
* FileSys::GetDiskSpace() - fill in data about filesystem space usage.
|
|
* FileSys::Seek() - seek to offset, FST_BINARY,TEXT,ATEXT only
|
|
* FileSys::Tell() - file position, FST_BINARY,TEXT,ATEXT only
|
|
*
|
|
* FileSys::ScanDir() - return a list of directory contents
|
|
* FileSys::MkDir() - make a directory for the current file
|
|
* FileSys::RmDir() - remove the directory of the current file
|
|
* FileSys::Rename() - rename file to target
|
|
* FileSys::ReadFile() - open, read whole file into string, close
|
|
* FileSys::WriteFile() - open, write whole file from string, close
|
|
* FileSys::Chmod() - change permissions
|
|
* FileSys::Compare() - compare file against target
|
|
* FileSys::Copy - copy one file to another
|
|
* FileSys::Digest() - return a fingerprint of the file contents
|
|
* FileSys::Chmod2() - copy a file to get ownership and set perms
|
|
* FileSys::Fsync() - sync file state to disk
|
|
*
|
|
* FileSys::CheckType() - look at the file and see if it is binary, etc
|
|
*/
|
|
|
|
enum FileSysType
|
|
{
|
|
// Base types
|
|
|
|
FST_TEXT = 0x0001, // file is text
|
|
FST_BINARY = 0x0002, // file is binary
|
|
FST_GZIP = 0x0003, // file is gzip
|
|
FST_DIRECTORY = 0x0005, // it's a directory
|
|
FST_SYMLINK = 0x0006, // it's a symlink
|
|
FST_RESOURCE = 0x0007, // Macintosh resource file
|
|
FST_SPECIAL = 0x0008, // not a regular file
|
|
FST_MISSING = 0x0009, // no file at all
|
|
FST_CANTTELL = 0x000A, // can read file to find out
|
|
FST_EMPTY = 0x000B, // file is empty
|
|
FST_UNICODE = 0x000C, // file is unicode
|
|
FST_GUNZIP = 0x000D, // stream is gzip
|
|
FST_UTF16 = 0x000E, // stream is utf8 convert to utf16
|
|
|
|
FST_MASK = 0x000F, // mask for types
|
|
|
|
// Modifiers
|
|
|
|
FST_M_APPEND = 0x0010, // open always append
|
|
FST_M_EXCL = 0x0020, // open exclusive create
|
|
FST_M_SYNC = 0x0040, // fsync on close
|
|
|
|
FST_M_EXEC = 0x0100, // file is executable
|
|
FST_M_APPLE = 0x0200, // apple single/double encoding
|
|
FST_M_COMP = 0x0400, // file is somehow compressed
|
|
|
|
FST_M_MASK = 0x0ff0, // mask for modifiers
|
|
|
|
// Line ending types, loosely mapped to LineType
|
|
|
|
FST_L_LOCAL = 0x0000, // LineTypeLocal
|
|
FST_L_LF = 0x1000, // LineTypeRaw
|
|
FST_L_CR = 0x2000, // LineTypeCr
|
|
FST_L_CRLF = 0x3000, // LineTypeCrLf
|
|
FST_L_LFCRLF = 0x4000, // LineTypeLfcrlf
|
|
|
|
FST_L_MASK = 0xf000, // mask for LineTypes
|
|
|
|
// Composite types, for filesys.cc
|
|
|
|
FST_ATEXT = 0x0011, // append-only text
|
|
FST_XTEXT = 0x0101, // executable text
|
|
FST_RTEXT = 0x1001, // raw text
|
|
FST_RXTEXT = 0x1101, // executable raw text
|
|
FST_CBINARY = 0x0402, // pre-compressed binary
|
|
FST_XBINARY = 0x0102, // executable binary
|
|
FST_APPLETEXT = 0x0201, // apple format text
|
|
FST_APPLEFILE = 0x0202, // apple format binary
|
|
FST_XAPPLEFILE = 0x0302, // executable apple format binary
|
|
FST_XUNICODE = 0x010C, // executable unicode text
|
|
FST_XUTF16 = 0x010E, // stream is utf8 convert to utf16
|
|
FST_RCS = 0x1041 // RCS temporary file: raw text, sync on close
|
|
|
|
};
|
|
|
|
enum FileStatFlags {
|
|
FSF_EXISTS = 0x01, // file exists
|
|
FSF_WRITEABLE = 0x02, // file is user-writable
|
|
FSF_DIRECTORY = 0x04, // file is a directory
|
|
FSF_SYMLINK = 0x08, // file is symlink
|
|
FSF_SPECIAL = 0x10, // file is not regular
|
|
FSF_EXECUTABLE = 0x20, // file is executable
|
|
FSF_EMPTY = 0x40, // file is empty
|
|
FSF_HIDDEN = 0x80 // file is invisible (hidden)
|
|
} ;
|
|
|
|
enum FileOpenMode {
|
|
FOM_READ, // open for reading
|
|
FOM_WRITE, // open for writing
|
|
FOM_RW // open for write, but don't trunc, allow read
|
|
} ;
|
|
|
|
enum FilePerm {
|
|
FPM_RO, // leave file read-only
|
|
FPM_RW, // leave file read-write
|
|
FPM_ROO, // leave file read-only (owner)
|
|
// following two enums are for key file and dir permissions
|
|
FPM_RXO, // set file read-execute (owner) NO W
|
|
FPM_RWO, // set file read-write (owner) NO X
|
|
FPM_RWXO // set file read-write-execute (owner)
|
|
} ;
|
|
|
|
class StrArray;
|
|
class CharSetCvt;
|
|
class MD5;
|
|
class StrBuf;
|
|
|
|
class DiskSpaceInfo {
|
|
|
|
public:
|
|
|
|
DiskSpaceInfo();
|
|
~DiskSpaceInfo();
|
|
|
|
P4INT64 blockSize;
|
|
P4INT64 totalBytes;
|
|
P4INT64 usedBytes;
|
|
P4INT64 freeBytes;
|
|
int pctUsed;
|
|
StrBuf *fsType;
|
|
} ;
|
|
|
|
class FileSys {
|
|
|
|
public:
|
|
// Creators
|
|
|
|
static FileSys *Create( FileSysType type );
|
|
|
|
static FileSys *CreateTemp( FileSysType type ) {
|
|
FileSys *f = Create( type );
|
|
f->SetDeleteOnClose();
|
|
return f;
|
|
}
|
|
|
|
static FileSys *CreateGlobalTemp( FileSysType type ) {
|
|
FileSys *f = Create( type );
|
|
f->SetDeleteOnClose();
|
|
f->MakeGlobalTemp();
|
|
return f;
|
|
}
|
|
|
|
static FilePerm Perm( const char *p );
|
|
|
|
static bool FileExists( const char *p );
|
|
|
|
static int BufferSize();
|
|
|
|
static bool IsRelative( const StrPtr &p );
|
|
|
|
virtual void SetBufferSize( size_t ) { }
|
|
|
|
int IsUnderPath( const StrPtr &path );
|
|
|
|
static int SymlinksSupported()
|
|
# ifdef OS_NT
|
|
; // Have to probe the system to decide
|
|
# else
|
|
# ifdef HAVE_SYMLINKS
|
|
{ return 1; }
|
|
# else
|
|
{ return 0; }
|
|
# endif
|
|
# endif
|
|
|
|
// Get/set perms, modtime
|
|
|
|
void Perms( FilePerm p ) { perms = p; }
|
|
void ModTime( StrPtr *u ) { modTime = u->Atoi(); }
|
|
void ModTime( time_t t ) { modTime = (int)t; }
|
|
|
|
// Set filesize hint for NT fragmentation avoidance
|
|
|
|
void SetSizeHint( offL_t l ) { sizeHint = l; }
|
|
offL_t GetSizeHint() { return sizeHint; }
|
|
|
|
// Set advise hint (don't pollute O.S cache with archive content)
|
|
|
|
virtual void SetCacheHint() { cacheHint = 1; }
|
|
|
|
// Initialize digest
|
|
|
|
virtual void SetDigest( MD5 *m );
|
|
|
|
// Get type info
|
|
|
|
FileSysType GetType() { return type; }
|
|
int IsExec() { return ( type & FST_M_EXEC ); }
|
|
int IsTextual() {
|
|
return ( type & FST_MASK ) == FST_TEXT ||
|
|
( type & FST_MASK ) == FST_UNICODE ||
|
|
( type & FST_MASK ) == FST_UTF16;
|
|
}
|
|
int IsUnicode() {
|
|
return ( type & FST_MASK ) == FST_UNICODE ||
|
|
( type & FST_MASK ) == FST_UTF16;
|
|
}
|
|
int IsSymlink() {
|
|
return ( type & FST_MASK ) == FST_SYMLINK;
|
|
}
|
|
|
|
|
|
// Read/write file access, provided by derived class
|
|
|
|
FileSys();
|
|
virtual ~FileSys();
|
|
|
|
virtual void Set( const StrPtr &name );
|
|
virtual void Set( const StrPtr &name, Error *e );
|
|
virtual StrPtr *Path() { return &path; }
|
|
virtual int DoIndirectWrites();
|
|
virtual void Translator( CharSetCvt * );
|
|
|
|
virtual void Open( FileOpenMode mode, Error *e ) = 0;
|
|
virtual void Write( const char *buf, int len, Error *e ) = 0;
|
|
virtual int Read( char *buf, int len, Error *e ) = 0;
|
|
virtual void Close( Error *e ) = 0;
|
|
|
|
|
|
virtual int Stat() = 0;
|
|
virtual int StatModTime() = 0;
|
|
virtual void Truncate( Error *e ) = 0;
|
|
virtual void Truncate( offL_t offset, Error *e ) = 0;
|
|
virtual void Unlink( Error *e = 0 ) = 0;
|
|
virtual void Rename( FileSys *target, Error *e ) = 0;
|
|
// Note: Readlink in NOT IMPLEMENTED on Windows, sets Fatal error
|
|
virtual int Readlink( StrBuf &linkPath, Error *e );
|
|
// Note: Writelink in NOT IMPLEMENTED on Windows, sets Fatal error
|
|
virtual int Writelink( const StrPtr &linkPath, Error *e );
|
|
virtual void Chmod( FilePerm perms, Error *e ) = 0;
|
|
virtual void ChmodTime( Error *e ) = 0;
|
|
|
|
virtual void Fsync( Error *e ) { }
|
|
|
|
// NB: these for ReadFile only; interface will likely change
|
|
virtual bool HasOnlyPerm( FilePerm perms );
|
|
virtual int GetFd();
|
|
virtual int GetOwner();
|
|
virtual offL_t GetSize();
|
|
virtual void Seek( offL_t offset, Error * );
|
|
virtual offL_t Tell();
|
|
|
|
// Convenience wrappers for above
|
|
|
|
void Chmod( Error *e ) { Chmod( perms, e ); }
|
|
void Chmod( const char *perms, Error *e )
|
|
{ Chmod( Perm( perms ), e ); }
|
|
|
|
char * Name() { return Path()->Text(); }
|
|
void Set( const char *name ) { Set( StrRef( name ) ); }
|
|
void Set( const char *name, Error *e )
|
|
{ Set( StrRef( name ), e ); }
|
|
|
|
void Write( const StrPtr &b, Error *e )
|
|
{ Write( b.Text(), b.Length(), e ); }
|
|
|
|
void Write( const StrPtr *b, Error *e )
|
|
{ Write( b->Text(), b->Length(), e ); }
|
|
|
|
// Tempfile support
|
|
|
|
void MakeGlobalTemp();
|
|
virtual void MakeLocalTemp( char *file );
|
|
int IsDeleteOnClose() { return isTemp; }
|
|
void SetDeleteOnClose() { isTemp = 1; }
|
|
void ClearDeleteOnClose() { isTemp = 0; }
|
|
|
|
// Meta operations
|
|
|
|
virtual StrArray *ScanDir( Error *e );
|
|
|
|
virtual void MkDir( const StrPtr &p, Error *e );
|
|
void MkDir( Error *e ) { MkDir( path, e ); }
|
|
|
|
virtual void RmDir( const StrPtr &p, Error *e );
|
|
void RmDir( Error *e = 0 ) { RmDir( path, e ); }
|
|
|
|
FileSysType CheckType( int scan = -1 );
|
|
|
|
# if defined ( OS_MACOSX )
|
|
FileSysType CheckTypeMac();
|
|
# endif
|
|
|
|
// Type generic operations
|
|
|
|
virtual int ReadLine( StrBuf *buf, Error *e );
|
|
void ReadWhole( StrBuf *buf, Error *e );
|
|
|
|
// Type generic, whole file operations
|
|
|
|
void ReadFile( StrBuf *buf, Error *e );
|
|
void WriteFile( const StrPtr *buf, Error *e );
|
|
int Compare( FileSys *other, Error *e );
|
|
void Copy( FileSys *targetFile, FilePerm perms, Error *e );
|
|
virtual void Digest( StrBuf *digest, Error *e );
|
|
void Chmod2( FilePerm perms, Error *e );
|
|
void Chmod2( const char *p, Error *e )
|
|
{ Chmod2( Perm( p ), e ); }
|
|
|
|
void Cleanup();
|
|
|
|
// Character Set operations
|
|
|
|
void SetCharSetPriv( int x = 0 ) { charSet = x; }
|
|
int GetCharSetPriv() { return charSet; }
|
|
void SetContentCharSetPriv( int x = 0 ) { content_charSet = x; }
|
|
int GetContentCharSetPriv() { return content_charSet; }
|
|
|
|
void GetDiskSpace( DiskSpaceInfo *info, Error *e );
|
|
|
|
void LowerCasePath();
|
|
protected:
|
|
|
|
FileOpenMode mode; // read or write
|
|
FilePerm perms; // leave read-only or read-write
|
|
int modTime; // stamp file mod date on close
|
|
offL_t sizeHint; // how big will the file get ?
|
|
StrBuf path;
|
|
FileSysType type;
|
|
MD5 *checksum; // if verifying file transfer
|
|
int cacheHint; // don't pollute cache
|
|
|
|
private:
|
|
void TempName( char *buf );
|
|
|
|
int isTemp;
|
|
|
|
int charSet;
|
|
int content_charSet;
|
|
|
|
} ;
|