Added a file abtraction layer into the Host section of LLDB.

llvm-svn: 125093
This commit is contained in:
Greg Clayton 2011-02-08 17:49:02 +00:00
parent 7d90bf5551
commit 504f89a7e8
5 changed files with 335 additions and 2 deletions

View File

@ -205,7 +205,7 @@ public:
/// A mach error code.
//------------------------------------------------------------------
void
SetError (uint32_t err);
SetMachError (uint32_t err);
//------------------------------------------------------------------
/// Set accesssor with an error value and type.

View File

@ -0,0 +1,179 @@
//===-- File.h --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_File_h_
#define liblldb_File_h_
#if defined(__cplusplus)
#include "lldb/lldb-private.h"
#include "lldb/Host/FileSpec.h"
namespace lldb_private {
//----------------------------------------------------------------------
/// @class File File.h "lldb/Host/File.h"
/// @brief A file class.
///
/// A file class that divides abstracts the LLDB core from host file
/// functionality.
//----------------------------------------------------------------------
class File
{
public:
enum OpenOptions
{
eOpenOptionRead = (1u << 0), // Open file for reading
eOpenOptionWrite = (1u << 1), // Open file for writing
eOpenOptionAppend = (1u << 2), // Don't truncate file when opening, append to end of file
eOpenOptionNonBlocking = (1u << 3), // File reads
eOpenOptionCanCreate = (1u << 4), // Create file if doesn't already exist
eOpenOptionCanCreateNewOnly = (1u << 5), // Can create file only if it doesn't already exist
eOpenOptionTruncate = (1u << 6), // Truncate file when opening existing
eOpenOptionSharedLock = (1u << 7), // Open file and get shared lock
eOpenOptionExclusiveLock = (1u << 8) // Open file and get exclusive lock
};
enum Permissions
{
ePermissionsUserRead = (1u << 0),
ePermissionsUserWrite = (1u << 1),
ePermissionsUserExecute = (1u << 2),
ePermissionsGroupRead = (1u << 3),
ePermissionsGroupWrite = (1u << 4),
ePermissionsGroupExecute = (1u << 5),
ePermissionsWorldRead = (1u << 6),
ePermissionsWorldWrite = (1u << 7),
ePermissionsWorldExecute = (1u << 8)
};
File() :
m_file_spec (),
m_file_desc (-1)
{
}
//------------------------------------------------------------------
/// Constructor with path.
///
/// Takes a path to a file which can be just a filename, or a full
/// path. If \a path is not NULL or empty, this function will call
/// FileSpec::SetFile (const char *path, bool resolve).
///
/// @param[in] path
/// The full or partial path to a file.
///
/// @param[in] options
/// Options to use when opening (see OpenOptions)
///
/// @param[in] permissions
/// Options to use when opening (see OpenOptions)
///
/// @see FileSpec::SetFile (const char *path, bool resolve)
//------------------------------------------------------------------
File (const char *path,
uint32_t options,
uint32_t permissions);
//------------------------------------------------------------------
/// Destructor.
///
/// The destructor is virtual in case this class is subclassed.
//------------------------------------------------------------------
virtual
~File ();
bool
IsValid () const
{
return m_file_desc >= 0;
}
//------------------------------------------------------------------
/// Convert to pointer operator.
///
/// This allows code to check a File object to see if it
/// contains anything valid using code such as:
///
/// @code
/// File file(...);
/// if (file)
/// { ...
/// @endcode
///
/// @return
/// A pointer to this object if either the directory or filename
/// is valid, NULL otherwise.
//------------------------------------------------------------------
operator
bool () const
{
return m_file_desc >= 0;
}
//------------------------------------------------------------------
/// Logical NOT operator.
///
/// This allows code to check a File object to see if it is
/// invalid using code such as:
///
/// @code
/// File file(...);
/// if (!file)
/// { ...
/// @endcode
///
/// @return
/// Returns \b true if the object has an empty directory and
/// filename, \b false otherwise.
//------------------------------------------------------------------
bool
operator! () const
{
return m_file_desc < 0;
}
//------------------------------------------------------------------
/// Get the file spec for this file.
///
/// @return
/// A reference to the file specification object.
//------------------------------------------------------------------
const FileSpec &
GetFileSpec () const
{
return m_file_spec;
}
Error
Open (const char *path,
uint32_t options,
uint32_t permissions);
Error
Close ();
Error
Read (void *dst, size_t &num_bytes);
Error
Write (const void *src, size_t &num_bytes);
protected:
//------------------------------------------------------------------
// Member variables
//------------------------------------------------------------------
FileSpec m_file_spec; ///< The file specific for the current file (if any)
int m_file_desc; ///< The open file handle or NULL if the file isn't opened
};
} // namespace lldb_private
#endif // #if defined(__cplusplus)
#endif // liblldb_FileSpec_h_

View File

@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
260C6EA113011578005E16B0 /* File.h in Headers */ = {isa = PBXBuildFile; fileRef = 260C6EA013011578005E16B0 /* File.h */; };
260C6EA313011581005E16B0 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C6EA213011581005E16B0 /* File.cpp */; };
260C876A10F538E700BB2B04 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 260C876910F538E700BB2B04 /* Foundation.framework */; };
2615DB871208A9E40021781D /* StopInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2615DB861208A9E40021781D /* StopInfo.cpp */; };
2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2615DBC81208B5FC0021781D /* StopInfoMachException.cpp */; };
@ -437,6 +439,8 @@
260223E8115F06E500A601A2 /* SBCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBCommunication.cpp; path = source/API/SBCommunication.cpp; sourceTree = "<group>"; };
26022531115F27FA00A601A2 /* SBFileSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFileSpec.h; path = include/lldb/API/SBFileSpec.h; sourceTree = "<group>"; };
26022532115F281400A601A2 /* SBFileSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBFileSpec.cpp; path = source/API/SBFileSpec.cpp; sourceTree = "<group>"; };
260C6EA013011578005E16B0 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = File.h; path = include/lldb/Host/File.h; sourceTree = "<group>"; };
260C6EA213011581005E16B0 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = "<group>"; };
260C847110F50EFC00BB2B04 /* ThreadPlanBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanBase.cpp; path = source/Target/ThreadPlanBase.cpp; sourceTree = "<group>"; };
260C847210F50EFC00BB2B04 /* ThreadPlanStepInstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepInstruction.cpp; path = source/Target/ThreadPlanStepInstruction.cpp; sourceTree = "<group>"; };
260C847310F50EFC00BB2B04 /* ThreadPlanStepOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepOut.cpp; path = source/Target/ThreadPlanStepOut.cpp; sourceTree = "<group>"; };
@ -1972,6 +1976,7 @@
26BC7DD210F1B7D500F91463 /* Condition.h */,
266F5CBB12FC846200DFCE33 /* Config.h */,
26BC7DD310F1B7D500F91463 /* Endian.h */,
260C6EA013011578005E16B0 /* File.h */,
26FA4315130103F400E71120 /* FileSpec.h */,
26BC7DD410F1B7D500F91463 /* Host.h */,
26BC7DD510F1B7D500F91463 /* Mutex.h */,
@ -2273,6 +2278,7 @@
69A01E1A1236C5D400C660B5 /* common */ = {
isa = PBXGroup;
children = (
260C6EA213011581005E16B0 /* File.cpp */,
26FA43171301048600E71120 /* FileSpec.cpp */,
69A01E1B1236C5D400C660B5 /* Condition.cpp */,
69A01E1C1236C5D400C660B5 /* Host.cpp */,
@ -2349,6 +2355,7 @@
266F5CBC12FC846200DFCE33 /* Config.h in Headers */,
268DA872130095D000C9483A /* Terminal.h in Headers */,
26FA4316130103F400E71120 /* FileSpec.h in Headers */,
260C6EA113011578005E16B0 /* File.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2854,6 +2861,7 @@
4906FD4212F2255300A2A77C /* ASTDumper.cpp in Sources */,
268DA874130095ED00C9483A /* Terminal.cpp in Sources */,
26FA43181301048600E71120 /* FileSpec.cpp in Sources */,
260C6EA313011581005E16B0 /* File.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -244,7 +244,7 @@ Error::LogIfError (Log *log, const char *format, ...)
// "eErrorTypeMachKernel"
//----------------------------------------------------------------------
void
Error::SetError (uint32_t err)
Error::SetMachError (uint32_t err)
{
m_code = err;
m_type = eErrorTypeMachKernel;

View File

@ -0,0 +1,146 @@
//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Host/File.h"
#include <fcntl.h>
#include "lldb/Core/Error.h"
using namespace lldb;
using namespace lldb_private;
File::File(const char *path, uint32_t options, uint32_t permissions) :
m_file_spec (path, false),
m_file_desc (-1)
{
Open (path, options, permissions);
}
File::~File()
{
Close ();
}
Error
File::Open (const char *path, uint32_t options, uint32_t permissions)
{
Error error;
if (IsValid())
Close ();
int oflag = 0;
if (options & eOpenOptionRead &&
options & eOpenOptionWrite )
oflag |= O_RDWR;
else if (options & eOpenOptionRead)
oflag |= O_RDONLY;
else if (options & eOpenOptionWrite)
oflag |= O_WRONLY;
if (options & eOpenOptionNonBlocking)
oflag |= O_NONBLOCK;
if (options & eOpenOptionAppend)
oflag |= O_APPEND;
if (options & eOpenOptionCanCreate)
oflag |= O_CREAT;
if (options & eOpenOptionCanCreateNewOnly)
oflag |= O_CREAT | O_EXCL;
if (options & eOpenOptionTruncate)
oflag |= O_TRUNC;
if (options & eOpenOptionSharedLock)
oflag |= O_SHLOCK;
if (options & eOpenOptionExclusiveLock)
oflag |= O_EXLOCK;
mode_t mode = 0;
if (permissions & ePermissionsUserRead) mode |= S_IRUSR;
if (permissions & ePermissionsUserWrite) mode |= S_IWUSR;
if (permissions & ePermissionsUserExecute) mode |= S_IXUSR;
if (permissions & ePermissionsGroupRead) mode |= S_IRGRP;
if (permissions & ePermissionsGroupWrite) mode |= S_IWGRP;
if (permissions & ePermissionsGroupExecute) mode |= S_IXGRP;
if (permissions & ePermissionsWorldRead) mode |= S_IROTH;
if (permissions & ePermissionsWorldWrite) mode |= S_IWOTH;
if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH;
m_file_desc = ::open(path, oflag, mode);
if (m_file_desc == -1)
error.SetErrorToErrno();
else
m_file_spec.SetFile (path, false);
return error;
}
Error
File::Close ()
{
Error error;
if (IsValid ())
{
if (::close (m_file_desc) != 0)
error.SetErrorToErrno();
}
return error;
}
Error
File::Read (void *buf, size_t &num_bytes)
{
Error error;
if (IsValid ())
{
ssize_t bytes_read = ::read (m_file_desc, buf, num_bytes);
if (bytes_read == -1)
{
error.SetErrorToErrno();
num_bytes = 0;
}
else
num_bytes = bytes_read;
}
else
{
num_bytes = 0;
error.SetErrorString("invalid file handle");
}
return error;
}
Error
File::Write (const void *buf, size_t &num_bytes)
{
Error error;
if (IsValid())
{
ssize_t bytes_written = ::write (m_file_desc, buf, num_bytes);
if (bytes_written == -1)
{
error.SetErrorToErrno();
num_bytes = 0;
}
else
num_bytes = bytes_written;
}
else
{
num_bytes = 0;
error.SetErrorString("invalid file handle");
}
return error;
}