//===-- 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 #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; }