llvm-project/lldb/source/Host/common/File.cpp

292 lines
6.0 KiB
C++
Raw Normal View History

//===-- 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"
#include "lldb/Host/FileSpec.h"
using namespace lldb;
using namespace lldb_private;
File::File(const char *path, uint32_t options, uint32_t permissions) :
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();
return error;
}
Error
File::Close ()
{
Error error;
if (IsValid ())
{
if (::close (m_file_desc) != 0)
error.SetErrorToErrno();
m_file_desc = -1;
}
return error;
}
Error
File::GetFileSpec (FileSpec &file_spec) const
{
Error error;
if (IsValid ())
{
char path[PATH_MAX];
if (::fcntl(m_file_desc, F_GETPATH, path) == -1)
error.SetErrorToErrno();
else
file_spec.SetFile (path, false);
}
else
error.SetErrorString("invalid file handle");
if (error.Fail())
file_spec.Clear();
return error;
}
Error
File::SeekFromStart (off_t& offset)
{
Error error;
if (IsValid ())
{
offset = ::lseek (m_file_desc, offset, SEEK_SET);
if (offset == -1)
error.SetErrorToErrno();
}
else
{
error.SetErrorString("invalid file handle");
}
return error;
}
Error
File::SeekFromCurrent (off_t& offset)
{
Error error;
if (IsValid ())
{
offset = ::lseek (m_file_desc, offset, SEEK_CUR);
if (offset == -1)
error.SetErrorToErrno();
}
else
{
error.SetErrorString("invalid file handle");
}
return error;
}
Error
File::SeekFromEnd (off_t& offset)
{
Error error;
if (IsValid ())
{
offset = ::lseek (m_file_desc, offset, SEEK_CUR);
if (offset == -1)
error.SetErrorToErrno();
}
else
{
error.SetErrorString("invalid file handle");
}
return error;
}
Error
File::Sync ()
{
Error error;
if (IsValid ())
{
if (::fsync (m_file_desc) == -1)
error.SetErrorToErrno();
}
else
{
error.SetErrorString("invalid file handle");
}
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;
}
Error
File::Read (void *buf, size_t &num_bytes, off_t &offset)
{
Error error;
if (IsValid ())
{
ssize_t bytes_read = ::pread (m_file_desc, buf, num_bytes, offset);
if (bytes_read < 0)
{
num_bytes = 0;
error.SetErrorToErrno();
}
else
{
offset += bytes_read;
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, off_t &offset)
{
Error error;
if (IsValid())
{
ssize_t bytes_written = ::pwrite (m_file_desc, buf, num_bytes, offset);
if (bytes_written < 0)
{
num_bytes = 0;
error.SetErrorToErrno();
}
else
{
offset += bytes_written;
num_bytes = bytes_written;
}
}
else
{
num_bytes = 0;
error.SetErrorString("invalid file handle");
}
return error;
}