Refactor many file functions to use FileSpec over strings.

Summary:
This should solve the issue of sending denormalized paths over gdb-remote
if we stick to GetPath(false) in GDBRemoteCommunicationClient, and let the
server handle any denormalization.

Reviewers: ovyalov, zturner, vharron, clayborg

Reviewed By: clayborg

Subscribers: tberghammer, emaste, lldb-commits

Differential Revision: http://reviews.llvm.org/D9728

llvm-svn: 238604
This commit is contained in:
Chaoren Lin 2015-05-29 19:52:29 +00:00
parent 375432e4d8
commit d3173f34e8
51 changed files with 837 additions and 775 deletions

View File

@ -233,7 +233,7 @@ public:
const char *
AsCString(const char *value_if_empty = NULL) const
{
if (m_string == NULL)
if (IsEmpty())
return value_if_empty;
return m_string;
}

View File

@ -470,7 +470,7 @@ public:
GetPermissions(Error &error) const;
static uint32_t
GetPermissions (const char *path, Error &error);
GetPermissions(const FileSpec &file_spec, Error &error);
//------------------------------------------------------------------

View File

@ -80,6 +80,10 @@ public:
explicit FileSpec (const char *path, bool resolve_path, ArchSpec arch);
explicit FileSpec(const std::string &path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative);
explicit FileSpec(const std::string &path, bool resolve_path, ArchSpec arch);
//------------------------------------------------------------------
/// Copy constructor
///
@ -410,6 +414,9 @@ public:
std::string
GetPath (bool denormalize = true) const;
const char *
GetCString(bool denormalize = true) const;
//------------------------------------------------------------------
/// Extract the full path to the file.
///
@ -661,6 +668,9 @@ public:
void
SetFile (const char *path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative);
void
SetFile(const std::string &path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative);
bool
IsResolved () const
{
@ -719,7 +729,10 @@ public:
void
AppendPathComponent (const char *new_path);
void
AppendPathComponent(const std::string &new_path);
void
RemoveLastPathComponent ();

View File

@ -24,18 +24,20 @@ class FileSystem
public:
static FileSpec::PathSyntax GetNativePathSyntax();
static Error MakeDirectory(const char *path, uint32_t mode);
static Error DeleteDirectory(const char *path, bool recurse);
static Error MakeDirectory(const FileSpec &file_spec, uint32_t mode);
static Error DeleteDirectory(const FileSpec &file_spec, bool recurse);
static Error GetFilePermissions(const char *path, uint32_t &file_permissions);
static Error SetFilePermissions(const char *path, uint32_t file_permissions);
static Error GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions);
static Error SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions);
static lldb::user_id_t GetFileSize(const FileSpec &file_spec);
static bool GetFileExists(const FileSpec &file_spec);
static Error Hardlink(const char *src, const char *dst);
static Error Symlink(const char *src, const char *dst);
static Error Readlink(const char *path, char *buf, size_t buf_len);
static Error Unlink(const char *path);
static Error Hardlink(const FileSpec &src, const FileSpec &dst);
static Error Symlink(const FileSpec &src, const FileSpec &dst);
static Error Readlink(const FileSpec &src, FileSpec &dst);
static Error Unlink(const FileSpec &file_spec);
static bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high);
static bool CalculateMD5(const FileSpec &file_spec,

View File

@ -261,22 +261,22 @@ public:
ShellExpandArguments (ProcessLaunchInfo &launch_info);
static Error
RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec,
bool run_in_default_shell = true);
RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec,
bool run_in_default_shell = true);
static Error
RunShellCommand (const Args& args,
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec,
bool run_in_default_shell = true);
RunShellCommand(const Args& args,
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec,
bool run_in_default_shell = true);
static lldb::DataBufferSP
GetAuxvData (lldb_private::Process *process);

View File

@ -11,6 +11,7 @@
#define liblldb_Target_FileAction_h
#include <string>
#include "lldb/Host/FileSpec.h"
namespace lldb_private
{
@ -34,7 +35,7 @@ class FileAction
bool Duplicate(int fd, int dup_fd);
bool Open(int fd, const char *path, bool read, bool write);
bool Open(int fd, const FileSpec &file_spec, bool read, bool write);
int
GetFD() const
@ -54,16 +55,20 @@ class FileAction
return m_arg;
}
const char *GetPath() const;
const char *
GetPath() const;
const FileSpec &
GetFileSpec() const;
void
Dump (Stream &stream) const;
protected:
Action m_action; // The action for this file
int m_fd; // An existing file descriptor
int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
std::string m_path; // A file path to use for opening after fork or posix_spawn
Action m_action; // The action for this file
int m_fd; // An existing file descriptor
int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
FileSpec m_file_spec; // A file spec to use for opening after fork or posix_spawn
};
} // namespace lldb_private

View File

@ -27,6 +27,7 @@
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Mutex.h"
// TODO pull NativeDelegate class out of NativeProcessProtocol so we
@ -316,15 +317,15 @@ class ModuleCache;
{
return ArchSpec(); // Return an invalid architecture
}
virtual ConstString
virtual FileSpec
GetRemoteWorkingDirectory()
{
return m_working_dir;
}
virtual bool
SetRemoteWorkingDirectory(const ConstString &path);
SetRemoteWorkingDirectory(const FileSpec &working_dir);
virtual const char *
GetUserName (uint32_t uid);
@ -632,12 +633,12 @@ class ModuleCache;
virtual void
AddClangModuleCompilationOptions (Target *target, std::vector<std::string> &options);
ConstString
GetWorkingDirectory ();
FileSpec
GetWorkingDirectory();
bool
SetWorkingDirectory (const ConstString &path);
SetWorkingDirectory(const FileSpec &working_dir);
// There may be modules that we don't want to find by default for operations like "setting breakpoint by name".
// The platform will return "true" from this call if the passed in module happens to be one of these.
@ -648,13 +649,13 @@ class ModuleCache;
}
virtual Error
MakeDirectory (const char *path, uint32_t permissions);
virtual Error
GetFilePermissions (const char *path, uint32_t &file_permissions);
MakeDirectory(const FileSpec &file_spec, uint32_t permissions);
virtual Error
SetFilePermissions (const char *path, uint32_t file_permissions);
GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions);
virtual Error
SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions);
virtual lldb::user_id_t
OpenFile (const FileSpec& file_spec,
@ -711,8 +712,8 @@ class ModuleCache;
uint32_t gid = UINT32_MAX);
virtual Error
CreateSymlink (const char *src, // The name of the link is in src
const char *dst);// The symlink points to dst
CreateSymlink(const FileSpec &src, // The name of the link is in src
const FileSpec &dst); // The symlink points to dst
//----------------------------------------------------------------------
/// Install a file or directory to the remote system.
@ -748,7 +749,7 @@ class ModuleCache;
GetFileExists (const lldb_private::FileSpec& file_spec);
virtual Error
Unlink (const char *path);
Unlink(const FileSpec &file_spec);
virtual uint64_t
ConvertMmapFlagsToPlatform(unsigned flags);
@ -832,13 +833,13 @@ class ModuleCache;
}
virtual lldb_private::Error
RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
virtual void
SetLocalCacheDirectory (const char* local);
@ -1008,7 +1009,7 @@ class ModuleCache;
bool m_system_arch_set_while_connected;
ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
ConstString m_sdk_build;
ConstString m_working_dir; // The working directory which is used when installing modules that have no install path set
FileSpec m_working_dir; // The working directory which is used when installing modules that have no install path set
std::string m_remote_url;
std::string m_name;
uint32_t m_major_os_version;

View File

@ -36,11 +36,11 @@ namespace lldb_private
ProcessLaunchInfo ();
ProcessLaunchInfo (const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
const char *working_directory,
uint32_t launch_flags);
ProcessLaunchInfo(const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
uint32_t launch_flags);
void
AppendFileAction (const FileAction &info)
@ -55,7 +55,8 @@ namespace lldb_private
AppendDuplicateFileAction (int fd, int dup_fd);
bool
AppendOpenFileAction (int fd, const char *path, bool read, bool write);
AppendOpenFileAction(int fd, const FileSpec &file_spec,
bool read, bool write);
bool
AppendSuppressFileAction (int fd, bool read, bool write);
@ -88,17 +89,11 @@ namespace lldb_private
return m_flags;
}
const char *
GetWorkingDirectory () const;
const FileSpec &
GetWorkingDirectory() const;
void
SetWorkingDirectory (const char *working_dir);
void
SwapWorkingDirectory (std::string &working_dir)
{
m_working_dir.swap (working_dir);
}
SetWorkingDirectory(const FileSpec &working_dir);
const char *
GetProcessPluginName () const;
@ -238,7 +233,7 @@ namespace lldb_private
}
protected:
std::string m_working_dir;
FileSpec m_working_dir;
std::string m_plugin_name;
FileSpec m_shell;
Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags

View File

@ -173,13 +173,13 @@ SBLaunchInfo::Clear ()
const char *
SBLaunchInfo::GetWorkingDirectory () const
{
return m_opaque_sp->GetWorkingDirectory();
return m_opaque_sp->GetWorkingDirectory().GetCString();
}
void
SBLaunchInfo::SetWorkingDirectory (const char *working_dir)
{
m_opaque_sp->SetWorkingDirectory(working_dir);
m_opaque_sp->SetWorkingDirectory(FileSpec{working_dir, false});
}
uint32_t
@ -260,7 +260,7 @@ SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd)
bool
SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write)
{
return m_opaque_sp->AppendOpenFileAction(fd, path, read, write);
return m_opaque_sp->AppendOpenFileAction(fd, FileSpec{path, false}, read, write);
}
bool

View File

@ -329,9 +329,9 @@ SBPlatform::SetWorkingDirectory(const char *path)
if (platform_sp)
{
if (path)
platform_sp->SetWorkingDirectory(ConstString(path));
platform_sp->SetWorkingDirectory(FileSpec{path, false});
else
platform_sp->SetWorkingDirectory(ConstString());
platform_sp->SetWorkingDirectory(FileSpec{});
return true;
}
return false;
@ -545,7 +545,7 @@ SBPlatform::Run (SBPlatformShellCommand &shell_command)
shell_command.SetWorkingDirectory(working_dir);
}
return platform_sp->RunShellCommand(command,
working_dir,
FileSpec{working_dir, false},
&shell_command.m_opaque_ptr->m_status,
&shell_command.m_opaque_ptr->m_signo,
&shell_command.m_opaque_ptr->m_output,
@ -598,7 +598,7 @@ SBPlatform::MakeDirectory (const char *path, uint32_t file_permissions)
PlatformSP platform_sp(GetSP());
if (platform_sp)
{
sb_error.ref() = platform_sp->MakeDirectory(path, file_permissions);
sb_error.ref() = platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
}
else
{
@ -614,7 +614,7 @@ SBPlatform::GetFilePermissions (const char *path)
if (platform_sp)
{
uint32_t file_permissions = 0;
platform_sp->GetFilePermissions(path, file_permissions);
platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
return file_permissions;
}
return 0;
@ -628,7 +628,7 @@ SBPlatform::SetFilePermissions (const char *path, uint32_t file_permissions)
PlatformSP platform_sp(GetSP());
if (platform_sp)
{
sb_error.ref() = platform_sp->SetFilePermissions(path, file_permissions);
sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false}, file_permissions);
}
else
{

View File

@ -167,11 +167,11 @@ SBProcess::RemoteLaunch (char const **argv,
{
if (stop_at_entry)
launch_flags |= eLaunchFlagStopAtEntry;
ProcessLaunchInfo launch_info (stdin_path,
stdout_path,
stderr_path,
working_directory,
launch_flags);
ProcessLaunchInfo launch_info(FileSpec{stdin_path, false},
FileSpec{stdout_path, false},
FileSpec{stderr_path, false},
FileSpec{working_directory, false},
launch_flags);
Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer();
if (exe_module)
launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);

View File

@ -343,7 +343,11 @@ SBTarget::Launch
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
launch_flags |= eLaunchFlagDisableSTDIO;
ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);
ProcessLaunchInfo launch_info(FileSpec{stdin_path, false},
FileSpec{stdout_path, false},
FileSpec{stderr_path, false},
FileSpec{working_directory, false},
launch_flags);
Module *exe_module = target_sp->GetExecutableModulePointer();
if (exe_module)

View File

@ -556,7 +556,7 @@ protected:
if (platform_sp)
{
if (m_option_working_dir.GetOptionValue().OptionWasSet())
platform_sp->SetWorkingDirectory (ConstString(m_option_working_dir.GetOptionValue().GetCurrentValue().GetPath().c_str()));
platform_sp->SetWorkingDirectory(m_option_working_dir.GetOptionValue().GetCurrentValue());
}
else
{
@ -616,7 +616,7 @@ public:
mode = options_permissions->m_permissions;
else
mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX | lldb::eFilePermissionsWorldRX;
Error error = platform_sp->MakeDirectory(cmd_line.c_str(), mode);
Error error = platform_sp->MakeDirectory(FileSpec{cmd_line, false}, mode);
if (error.Success())
{
result.SetStatus (eReturnStatusSuccessFinishResult);
@ -2150,7 +2150,7 @@ public:
Error error;
if (platform_sp)
{
const char *working_dir = NULL;
FileSpec working_dir{};
std::string output;
int status = -1;
int signo = -1;

View File

@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/android/ProcessLauncherAndroid.h"
@ -19,9 +20,9 @@ using namespace lldb;
using namespace lldb_private;
static bool
DupDescriptor(const char *path, int fd, int flags)
DupDescriptor(const FileSpec &file_spec, int fd, int flags)
{
int target_fd = ::open(path, flags, 0666);
int target_fd = ::open(file_spec.GetCString(), flags, 0666);
if (target_fd == -1)
return false;
@ -63,23 +64,23 @@ ProcessLauncherAndroid::LaunchProcess(const ProcessLaunchInfo &launch_info, Erro
else if (pid == 0)
{
if (const lldb_private::FileAction *file_action = launch_info.GetFileActionForFD(STDIN_FILENO)) {
const char* path = file_action->GetPath();
if (path && ::strlen(path))
if (!DupDescriptor(path, STDIN_FILENO, O_RDONLY))
FileSpec file_spec = file_action->GetFileSpec();
if (file_spec)
if (!DupDescriptor(file_spec, STDIN_FILENO, O_RDONLY))
exit(-1);
}
if (const lldb_private::FileAction *file_action = launch_info.GetFileActionForFD(STDOUT_FILENO)) {
const char* path = file_action->GetPath();
if (path && ::strlen(path))
if (!DupDescriptor(path, STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
FileSpec file_spec = file_action->GetFileSpec();
if (file_spec)
if (!DupDescriptor(file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
exit(-1);
}
if (const lldb_private::FileAction *file_action = launch_info.GetFileActionForFD(STDERR_FILENO)) {
const char* path = file_action->GetPath();
if (path && ::strlen(path))
if (!DupDescriptor(path, STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
FileSpec file_spec = file_action->GetFileSpec();
if (file_spec)
if (!DupDescriptor(file_spec, STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
exit(-1);
}
@ -90,10 +91,10 @@ ProcessLauncherAndroid::LaunchProcess(const ProcessLaunchInfo &launch_info, Erro
FixupEnvironment(env);
const char **envp = env.GetConstArgumentVector();
const char *working_dir = launch_info.GetWorkingDirectory();
if (working_dir != nullptr && working_dir[0])
FileSpec working_dir = launch_info.GetWorkingDirectory();
if (working_dir)
{
if (::chdir(working_dir) != 0)
if (::chdir(working_dir.GetCString()) != 0)
exit(-1);
}

View File

@ -193,9 +193,9 @@ namespace lldb_private
{
if (m_path.empty() && m_history && !m_prefix.empty())
{
std::string parent_path = FileSpec ("~/.lldb", true).GetPath();
FileSpec parent_path{"~/.lldb", true};
char history_path[PATH_MAX];
if (FileSystem::MakeDirectory(parent_path.c_str(), lldb::eFilePermissionsDirectoryDefault).Success())
if (FileSystem::MakeDirectory(parent_path, lldb::eFilePermissionsDirectoryDefault).Success())
{
snprintf (history_path, sizeof (history_path), "~/.lldb/%s-history", m_prefix.c_str());
}

View File

@ -325,12 +325,12 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
}
uint32_t
File::GetPermissions (const char *path, Error &error)
File::GetPermissions(const FileSpec &file_spec, Error &error)
{
if (path && path[0])
if (file_spec)
{
struct stat file_stats;
if (::stat (path, &file_stats) == -1)
if (::stat(file_spec.GetCString(), &file_stats) == -1)
error.SetErrorToErrno();
else
{
@ -339,12 +339,7 @@ File::GetPermissions (const char *path, Error &error)
}
}
else
{
if (path)
error.SetErrorString ("invalid path");
else
error.SetErrorString ("empty path");
}
error.SetErrorString ("empty file spec");
return 0;
}

View File

@ -243,7 +243,17 @@ FileSpec::FileSpec(const char *pathname, bool resolve_path, PathSyntax syntax) :
}
FileSpec::FileSpec(const char *pathname, bool resolve_path, ArchSpec arch) :
FileSpec(pathname, resolve_path, arch.GetTriple().isOSWindows() ? ePathSyntaxWindows : ePathSyntaxPosix)
FileSpec{pathname, resolve_path, arch.GetTriple().isOSWindows() ? ePathSyntaxWindows : ePathSyntaxPosix}
{
}
FileSpec::FileSpec(const std::string &path, bool resolve_path, PathSyntax syntax) :
FileSpec{path.c_str(), resolve_path, syntax}
{
}
FileSpec::FileSpec(const std::string &path, bool resolve_path, ArchSpec arch) :
FileSpec{path.c_str(), resolve_path, arch}
{
}
@ -334,6 +344,12 @@ FileSpec::SetFile (const char *pathname, bool resolve, PathSyntax syntax)
m_directory.SetCString(normalized.c_str());
}
void
FileSpec::SetFile(const std::string &pathname, bool resolve, PathSyntax syntax)
{
return SetFile(pathname.c_str(), resolve, syntax);
}
//----------------------------------------------------------------------
// Convert to pointer operator. This allows code to check any FileSpec
// objects to see if they contain anything valid using code such as:
@ -755,7 +771,7 @@ FileSpec::GetPermissions () const
{
uint32_t file_permissions = 0;
if (*this)
FileSystem::GetFilePermissions(GetPath().c_str(), file_permissions);
FileSystem::GetFilePermissions(*this, file_permissions);
return file_permissions;
}
@ -829,6 +845,12 @@ FileSpec::GetPath(bool denormalize) const
return std::string(result.begin(), result.end());
}
const char *
FileSpec::GetCString(bool denormalize) const
{
return ConstString{GetPath(denormalize)}.AsCString(NULL);
}
void
FileSpec::GetPath(llvm::SmallVectorImpl<char> &path, bool denormalize) const
{
@ -1335,6 +1357,12 @@ FileSpec::AppendPathComponent (const char *new_path)
SetFile(stream.GetData(), resolve);
}
void
FileSpec::AppendPathComponent(const std::string &new_path)
{
return AppendPathComponent(new_path.c_str());
}
void
FileSpec::RemoveLastPathComponent ()
{

View File

@ -533,25 +533,25 @@ MonitorShellCommand (void *callback_baton,
}
Error
Host::RunShellCommand (const char *command,
const char *working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output_ptr,
uint32_t timeout_sec,
bool run_in_default_shell)
Host::RunShellCommand(const char *command,
const FileSpec &working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output_ptr,
uint32_t timeout_sec,
bool run_in_default_shell)
{
return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr, command_output_ptr, timeout_sec, run_in_default_shell);
}
Error
Host::RunShellCommand (const Args &args,
const char *working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output_ptr,
uint32_t timeout_sec,
bool run_in_default_shell)
Host::RunShellCommand(const Args &args,
const FileSpec &working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output_ptr,
uint32_t timeout_sec,
bool run_in_default_shell)
{
Error error;
ProcessLaunchInfo launch_info;
@ -597,11 +597,13 @@ Host::RunShellCommand (const Args &args,
llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", output_file_path);
}
}
FileSpec output_file_spec{output_file_path.c_str(), false};
launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
if (!output_file_path.empty())
if (output_file_spec)
{
launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path.c_str(), false, true);
launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false, true);
launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
}
else
@ -660,8 +662,7 @@ Host::RunShellCommand (const Args &args,
if (command_output_ptr)
{
command_output_ptr->clear();
FileSpec file_spec(output_file_path.c_str(), File::eOpenOptionRead);
uint64_t file_size = file_spec.GetByteSize();
uint64_t file_size = output_file_spec.GetByteSize();
if (file_size > 0)
{
if (file_size > command_output_ptr->max_size())
@ -670,18 +671,19 @@ Host::RunShellCommand (const Args &args,
}
else
{
command_output_ptr->resize(file_size);
file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
std::vector<char> command_output(file_size);
output_file_spec.ReadFileContents(0, command_output.data(), file_size, &error);
if (error.Success())
command_output_ptr->assign(command_output.data(), file_size);
}
}
}
}
shell_info->can_delete.SetValue(true, eBroadcastAlways);
}
FileSpec output_file_spec(output_file_path.c_str(), false);
if (FileSystem::GetFileExists(output_file_spec))
FileSystem::Unlink(output_file_path.c_str());
FileSystem::Unlink(output_file_spec);
// Handshake with the monitor thread, or just let it know in advance that
// it can delete "shell_info" in case we timed out and were not able to kill
// the process...
@ -832,16 +834,18 @@ Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &lau
current_dir[0] = '\0';
#endif
const char *working_dir = launch_info.GetWorkingDirectory();
FileSpec working_dir{launch_info.GetWorkingDirectory()};
if (working_dir)
{
#if defined (__APPLE__)
// Set the working directory on this thread only
if (__pthread_chdir (working_dir) < 0) {
if (__pthread_chdir(working_dir.GetCString()) < 0) {
if (errno == ENOENT) {
error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
error.SetErrorStringWithFormat("No such file or directory: %s",
working_dir.GetCString());
} else if (errno == ENOTDIR) {
error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir);
error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
working_dir.GetCString());
} else {
error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution.");
}
@ -855,10 +859,11 @@ Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &lau
return error;
}
if (::chdir(working_dir) == -1)
if (::chdir(working_dir.GetCString()) == -1)
{
error.SetError(errno, eErrorTypePOSIX);
error.LogIfError(log, "unable to change working directory to %s", working_dir);
error.LogIfError(log, "unable to change working directory to %s",
working_dir.GetCString());
return error;
}
#endif

View File

@ -40,7 +40,7 @@ namespace
// Remove the LLDB temporary directory if we have one. Set "recurse" to
// true to all files that were created for the LLDB process can be cleaned up.
FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true);
FileSystem::DeleteDirectory(tmpdir_file_spec, true);
}
//----------------------------------------------------------------------
@ -326,18 +326,15 @@ HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec)
if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec))
return false;
std::string pid_str;
llvm::raw_string_ostream pid_stream(pid_str);
pid_stream << Host::GetCurrentProcessID();
temp_file_spec.AppendPathComponent(pid_stream.str().c_str());
std::string final_path = temp_file_spec.GetPath();
if (!FileSystem::MakeDirectory(final_path.c_str(), eFilePermissionsDirectoryDefault).Success())
std::string pid_str{std::to_string(Host::GetCurrentProcessID())};
temp_file_spec.AppendPathComponent(pid_str);
if (!FileSystem::MakeDirectory(temp_file_spec, eFilePermissionsDirectoryDefault).Success())
return false;
// Make an atexit handler to clean up the process specify LLDB temp dir
// and all of its contents.
::atexit(CleanupProcessSpecificLLDBTempDir);
file_spec.GetDirectory().SetCStringWithLength(final_path.c_str(), final_path.size());
file_spec = temp_file_spec;
return true;
}
@ -370,7 +367,7 @@ HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec)
return false;
temp_file_spec.AppendPathComponent("lldb");
if (!FileSystem::MakeDirectory(temp_file_spec.GetPath().c_str(), eFilePermissionsDirectoryDefault).Success())
if (!FileSystem::MakeDirectory(temp_file_spec, eFilePermissionsDirectoryDefault).Success())
return false;
file_spec = temp_file_spec;

View File

@ -504,7 +504,7 @@ Error Socket::UnixDomainAccept(llvm::StringRef name, bool child_processes_inheri
saddr_un.sun_len = SUN_LEN (&saddr_un);
#endif
FileSystem::Unlink(name.data());
FileSystem::Unlink(FileSpec{name, true});
bool success = false;
if (::bind (listen_fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0)
{

View File

@ -411,9 +411,9 @@ LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &lau
if (arch_spec.IsValid())
command.Printf(" --arch=%s", arch_spec.GetArchitectureName());
const char *working_dir = launch_info.GetWorkingDirectory();
FileSpec working_dir{launch_info.GetWorkingDirectory()};
if (working_dir)
command.Printf(" --working-dir '%s'", working_dir);
command.Printf(" --working-dir '%s'", working_dir.GetCString());
else
{
char cwd[PATH_MAX];
@ -527,7 +527,7 @@ LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &lau
WaitForProcessToSIGSTOP(pid, 5);
}
FileSystem::Unlink(unix_socket_name);
FileSystem::Unlink(FileSpec{unix_socket_name, false});
[applescript release];
if (pid != LLDB_INVALID_PROCESS_ID)
launch_info.SetProcessID (pid);

View File

@ -35,70 +35,61 @@ FileSystem::GetNativePathSyntax()
}
Error
FileSystem::MakeDirectory(const char *path, uint32_t file_permissions)
FileSystem::MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions)
{
Error error;
if (path && path[0])
if (file_spec)
{
if (::mkdir(path, file_permissions) != 0)
Error error;
if (::mkdir(file_spec.GetCString(), file_permissions) == -1)
{
error.SetErrorToErrno();
errno = 0;
switch (error.GetError())
{
case ENOENT:
{
// Parent directory doesn't exist, so lets make it if we can
FileSpec spec(path, false);
if (spec.GetDirectory() && spec.GetFilename())
// Make the parent directory and try again
FileSpec parent_file_spec{file_spec.GetDirectory().GetCString(), false};
error = MakeDirectory(parent_file_spec, file_permissions);
if (error.Fail())
return error;
// Try and make the directory again now that the parent directory was made successfully
if (::mkdir(file_spec.GetCString(), file_permissions) == -1)
{
// Make the parent directory and try again
Error error2 = MakeDirectory(spec.GetDirectory().GetCString(), file_permissions);
if (error2.Success())
{
// Try and make the directory again now that the parent directory was made successfully
if (::mkdir(path, file_permissions) == 0)
error.Clear();
else
error.SetErrorToErrno();
}
error.SetErrorToErrno();
return error;
}
}
break;
case EEXIST:
{
FileSpec path_spec(path, false);
if (path_spec.IsDirectory())
error.Clear(); // It is a directory and it already exists
if (file_spec.IsDirectory())
return Error{}; // It is a directory and it already exists
}
break;
}
}
return error;
}
else
{
error.SetErrorString("empty path");
}
return error;
return Error{"empty path"};
}
Error
FileSystem::DeleteDirectory(const char *path, bool recurse)
FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse)
{
Error error;
if (path && path[0])
if (file_spec)
{
if (recurse)
{
StreamString command;
command.Printf("rm -rf \"%s\"", path);
command.Printf("rm -rf \"%s\"", file_spec.GetCString());
int status = ::system(command.GetString().c_str());
if (status != 0)
error.SetError(status, eErrorTypeGeneric);
}
else
{
if (::rmdir(path) != 0)
if (::rmdir(file_spec.GetCString()) != 0)
error.SetErrorToErrno();
}
}
@ -110,11 +101,11 @@ FileSystem::DeleteDirectory(const char *path, bool recurse)
}
Error
FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions)
FileSystem::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
{
Error error;
struct stat file_stats;
if (::stat(path, &file_stats) == 0)
if (::stat(file_spec.GetCString(), &file_stats) == 0)
{
// The bits in "st_mode" currently match the definitions
// for the file mode bits in unix.
@ -128,10 +119,10 @@ FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions)
}
Error
FileSystem::SetFilePermissions(const char *path, uint32_t file_permissions)
FileSystem::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
{
Error error;
if (::chmod(path, file_permissions) != 0)
if (::chmod(file_spec.GetCString(), file_permissions) != 0)
error.SetErrorToErrno();
return error;
}
@ -149,43 +140,45 @@ FileSystem::GetFileExists(const FileSpec &file_spec)
}
Error
FileSystem::Hardlink(const char *src, const char *dst)
FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
if (::link(dst, src) == -1)
if (::link(dst.GetCString(), src.GetCString()) == -1)
error.SetErrorToErrno();
return error;
}
Error
FileSystem::Symlink(const char *src, const char *dst)
FileSystem::Symlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
if (::symlink(dst, src) == -1)
if (::symlink(dst.GetCString(), src.GetCString()) == -1)
error.SetErrorToErrno();
return error;
}
Error
FileSystem::Unlink(const char *path)
FileSystem::Unlink(const FileSpec &file_spec)
{
Error error;
if (::unlink(path) == -1)
if (::unlink(file_spec.GetCString()) == -1)
error.SetErrorToErrno();
return error;
}
Error
FileSystem::Readlink(const char *path, char *buf, size_t buf_len)
FileSystem::Readlink(const FileSpec &src, FileSpec &dst)
{
Error error;
ssize_t count = ::readlink(path, buf, buf_len);
char buf[PATH_MAX];
ssize_t count = ::readlink(src.GetCString(), buf, sizeof(buf) - 1);
if (count < 0)
error.SetErrorToErrno();
else if (static_cast<size_t>(count) < (buf_len - 1))
buf[count] = '\0'; // Success
else
error.SetErrorString("'buf' buffer is too small to contain link contents");
{
buf[count] = '\0'; // Success
dst.SetFile(buf, false);
}
return error;
}

View File

@ -69,28 +69,25 @@ Error HostProcessPosix::GetMainModule(FileSpec &file_spec) const
// Use special code here because proc/[pid]/exe is a symbolic link.
char link_path[PATH_MAX];
char exe_path[PATH_MAX] = "";
if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", m_process) <= 0)
if (snprintf(link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", m_process) != 1)
{
error.SetErrorString("Unable to build /proc/<pid>/exe string");
return error;
}
error = FileSystem::Readlink(link_path, exe_path, llvm::array_lengthof(exe_path));
error = FileSystem::Readlink(FileSpec{link_path, false}, file_spec);
if (!error.Success())
return error;
const ssize_t len = strlen(exe_path);
// If the binary has been deleted, the link name has " (deleted)" appended.
// Remove if there.
static const ssize_t deleted_len = strlen(" (deleted)");
if (len > deleted_len &&
!strcmp(exe_path + len - deleted_len, " (deleted)"))
if (file_spec.GetFilename().GetStringRef().endswith(" (deleted)"))
{
exe_path[len - deleted_len] = 0;
const char *filename = file_spec.GetFilename().GetCString();
static const size_t deleted_len = strlen(" (deleted)");
const size_t len = file_spec.GetFilename().GetLength();
file_spec.GetFilename().SetCStringWithLength(filename, len - deleted_len);
}
file_spec.SetFile(exe_path, false);
return error;
}

View File

@ -335,7 +335,7 @@ PipePosix::Close()
Error
PipePosix::Delete(llvm::StringRef name)
{
return FileSystem::Unlink(name.data());
return FileSystem::Unlink(FileSpec{name.data(), true});
}
bool

View File

@ -23,12 +23,12 @@ FileSystem::GetNativePathSyntax()
}
Error
FileSystem::MakeDirectory(const char *path, uint32_t file_permissions)
FileSystem::MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions)
{
// On Win32, the mode parameter is ignored, as Windows files and directories support a
// different permission model than POSIX.
Error error;
const auto err_code = llvm::sys::fs::create_directories(path, true);
const auto err_code = llvm::sys::fs::create_directories(file_spec.GetPath(), true);
if (err_code)
{
error.SetErrorString(err_code.message().c_str());
@ -38,12 +38,12 @@ FileSystem::MakeDirectory(const char *path, uint32_t file_permissions)
}
Error
FileSystem::DeleteDirectory(const char *path, bool recurse)
FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse)
{
Error error;
if (!recurse)
{
BOOL result = ::RemoveDirectory(path);
BOOL result = ::RemoveDirectory(file_spec.GetCString());
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
}
@ -51,7 +51,7 @@ FileSystem::DeleteDirectory(const char *path, bool recurse)
{
// SHFileOperation() accepts a list of paths, and so must be double-null-terminated to
// indicate the end of the list.
std::string path_buffer(path);
std::string path_buffer{file_spec.GetPath()};
path_buffer.push_back(0);
SHFILEOPSTRUCT shfos = {0};
@ -68,7 +68,7 @@ FileSystem::DeleteDirectory(const char *path, bool recurse)
}
Error
FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions)
FileSystem::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
{
Error error;
error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__);
@ -76,7 +76,7 @@ FileSystem::GetFilePermissions(const char *path, uint32_t &file_permissions)
}
Error
FileSystem::SetFilePermissions(const char *path, uint32_t file_permissions)
FileSystem::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
{
Error error;
error.SetErrorStringWithFormat("%s is not supported on this host", __PRETTY_FUNCTION__);
@ -96,19 +96,19 @@ FileSystem::GetFileExists(const FileSpec &file_spec)
}
Error
FileSystem::Hardlink(const char *linkname, const char *target)
FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
if (!::CreateHardLink(linkname, target, nullptr))
if (!::CreateHardLink(src.GetCString(), dst.GetCString(), nullptr))
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
Error
FileSystem::Symlink(const char *linkname, const char *target)
FileSystem::Symlink(const FileSpec &src, const FileSpec &dst)
{
Error error;
DWORD attrib = ::GetFileAttributes(target);
DWORD attrib = ::GetFileAttributes(dst.GetCString());
if (attrib == INVALID_FILE_ATTRIBUTES)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
@ -116,38 +116,43 @@ FileSystem::Symlink(const char *linkname, const char *target)
}
bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY);
DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
BOOL result = ::CreateSymbolicLink(linkname, target, flag);
BOOL result = ::CreateSymbolicLink(src.GetCString(), dst.GetCString(), flag);
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
Error
FileSystem::Unlink(const char *path)
FileSystem::Unlink(const FileSpec &file_spec)
{
Error error;
BOOL result = ::DeleteFile(path);
BOOL result = ::DeleteFile(file_spec.GetCString());
if (!result)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
Error
FileSystem::Readlink(const char *path, char *buf, size_t buf_len)
FileSystem::Readlink(const FileSpec &src, FileSpec &dst)
{
Error error;
HANDLE h = ::CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT, NULL);
HANDLE h = ::CreateFile(src.GetCString(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (h == INVALID_HANDLE_VALUE)
{
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
return error;
}
char buf[PATH_MAX];
// Subtract 1 from the path length since this function does not add a null terminator.
DWORD result = ::GetFinalPathNameByHandle(h, buf, buf_len - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
DWORD result = ::GetFinalPathNameByHandle(h, buf, sizeof(buf) - 1,
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
if (result == 0)
error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
else
dst.SetFile(buf, false);
::CloseHandle(h);
return error;

View File

@ -52,7 +52,7 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, Erro
executable = launch_info.GetExecutableFile().GetPath();
launch_info.GetArguments().GetQuotedCommandString(commandLine);
BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags, NULL,
launch_info.GetWorkingDirectory(), &startupinfo, &pi);
launch_info.GetWorkingDirectory().GetCString(), &startupinfo, &pi);
if (result)
{
// Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.

View File

@ -134,12 +134,12 @@ PlatformFreeBSD::GetModuleSpec (const FileSpec& module_file_spec,
}
lldb_private::Error
PlatformFreeBSD::RunShellCommand (const char *command,
const char *working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output,
uint32_t timeout_sec)
PlatformFreeBSD::RunShellCommand(const char *command,
const FileSpec &working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output,
uint32_t timeout_sec)
{
if (IsHost())
return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);

View File

@ -77,12 +77,12 @@ public:
lldb_private::ModuleSpec &module_spec) override;
lldb_private::Error
RunShellCommand (const char *command,
const char *working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output,
uint32_t timeout_sec) override;
RunShellCommand(const char *command,
const lldb_private::FileSpec &working_dir,
int *status_ptr,
int *signo_ptr,
std::string *command_output,
uint32_t timeout_sec) override;
lldb_private::Error
ResolveExecutable (const lldb_private::ModuleSpec &module_spec,

View File

@ -324,7 +324,7 @@ static lldb_private::Error
MakeCacheFolderForFile (const FileSpec& module_cache_spec)
{
FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
return FileSystem::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault);
return FileSystem::MakeDirectory(module_cache_folder, eFilePermissionsDirectoryDefault);
}
static lldb_private::Error

View File

@ -293,7 +293,7 @@ PlatformMacOSX::GetFileWithUUID (const lldb_private::FileSpec &platform_file,
FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
// try to make the local directory first
Error err =
FileSystem::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault);
FileSystem::MakeDirectory(module_cache_folder, eFilePermissionsDirectoryDefault);
if (err.Fail())
return err;
err = GetFile(platform_file, module_cache_spec);

View File

@ -85,12 +85,12 @@ PlatformPOSIX::IsConnected () const
}
lldb_private::Error
PlatformPOSIX::RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
PlatformPOSIX::RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
{
if (IsHost())
return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
@ -104,30 +104,30 @@ PlatformPOSIX::RunShellCommand (const char *command, // Shouldn't be N
}
Error
PlatformPOSIX::MakeDirectory (const char *path, uint32_t file_permissions)
PlatformPOSIX::MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions)
{
if (m_remote_platform_sp)
return m_remote_platform_sp->MakeDirectory(path, file_permissions);
return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
else
return Platform::MakeDirectory(path ,file_permissions);
return Platform::MakeDirectory(file_spec ,file_permissions);
}
Error
PlatformPOSIX::GetFilePermissions (const char *path, uint32_t &file_permissions)
PlatformPOSIX::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
{
if (m_remote_platform_sp)
return m_remote_platform_sp->GetFilePermissions(path, file_permissions);
return m_remote_platform_sp->GetFilePermissions(file_spec, file_permissions);
else
return Platform::GetFilePermissions(path ,file_permissions);
return Platform::GetFilePermissions(file_spec ,file_permissions);
}
Error
PlatformPOSIX::SetFilePermissions (const char *path, uint32_t file_permissions)
PlatformPOSIX::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
{
if (m_remote_platform_sp)
return m_remote_platform_sp->SetFilePermissions(path, file_permissions);
return m_remote_platform_sp->SetFilePermissions(file_spec, file_permissions);
else
return Platform::SetFilePermissions(path ,file_permissions);
return Platform::SetFilePermissions(file_spec, file_permissions);
}
lldb::user_id_t
@ -316,7 +316,7 @@ PlatformPOSIX::GetFileSize (const FileSpec& file_spec)
}
Error
PlatformPOSIX::CreateSymlink(const char *src, const char *dst)
PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst)
{
if (IsHost())
return FileSystem::Symlink(src, dst);
@ -338,19 +338,19 @@ PlatformPOSIX::GetFileExists (const FileSpec& file_spec)
}
Error
PlatformPOSIX::Unlink (const char *path)
PlatformPOSIX::Unlink(const FileSpec &file_spec)
{
if (IsHost())
return FileSystem::Unlink(path);
return FileSystem::Unlink(file_spec);
else if (m_remote_platform_sp)
return m_remote_platform_sp->Unlink(path);
return m_remote_platform_sp->Unlink(file_spec);
else
return Platform::Unlink(path);
return Platform::Unlink(file_spec);
}
lldb_private::Error
PlatformPOSIX::GetFile (const lldb_private::FileSpec& source /* remote file path */,
const lldb_private::FileSpec& destination /* local file path */)
PlatformPOSIX::GetFile(const lldb_private::FileSpec &source, // remote file path
const lldb_private::FileSpec &destination) // local file path
{
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
@ -433,8 +433,8 @@ PlatformPOSIX::GetFile (const lldb_private::FileSpec& source /* remote file path
return Error("unable to open source file");
uint32_t permissions = 0;
error = GetFilePermissions(source.GetPath().c_str(), permissions);
error = GetFilePermissions(source, permissions);
if (permissions == 0)
permissions = lldb::eFilePermissionsFileDefault;
@ -535,7 +535,7 @@ PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec,
return false;
}
lldb_private::ConstString
FileSpec
PlatformPOSIX::GetRemoteWorkingDirectory()
{
if (IsRemote() && m_remote_platform_sp)
@ -545,12 +545,12 @@ PlatformPOSIX::GetRemoteWorkingDirectory()
}
bool
PlatformPOSIX::SetRemoteWorkingDirectory(const lldb_private::ConstString &path)
PlatformPOSIX::SetRemoteWorkingDirectory(const FileSpec &working_dir)
{
if (IsRemote() && m_remote_platform_sp)
return m_remote_platform_sp->SetRemoteWorkingDirectory(path);
return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
else
return Platform::SetRemoteWorkingDirectory(path);
return Platform::SetRemoteWorkingDirectory(working_dir);
}
bool

View File

@ -84,17 +84,18 @@ public:
GetFileSize (const lldb_private::FileSpec& file_spec) override;
lldb_private::Error
CreateSymlink(const char *src, const char *dst) override;
CreateSymlink(const lldb_private::FileSpec &src,
const lldb_private::FileSpec &dst) override;
lldb_private::Error
GetFile (const lldb_private::FileSpec& source,
const lldb_private::FileSpec& destination) override;
lldb_private::ConstString
GetFile(const lldb_private::FileSpec &source,
const lldb_private::FileSpec &destination) override;
lldb_private::FileSpec
GetRemoteWorkingDirectory() override;
bool
SetRemoteWorkingDirectory(const lldb_private::ConstString &path) override;
SetRemoteWorkingDirectory(const lldb_private::FileSpec &working_dir) override;
bool
GetRemoteOSVersion () override;
@ -115,27 +116,27 @@ public:
IsConnected () const override;
lldb_private::Error
RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) override;// Timeout in seconds to wait for shell program to finish
RunShellCommand(const char *command, // Shouldn't be NULL
const lldb_private::FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) override; // Timeout in seconds to wait for shell program to finish
lldb_private::Error
MakeDirectory (const char *path, uint32_t mode) override;
lldb_private::Error
GetFilePermissions (const char *path, uint32_t &file_permissions) override;
MakeDirectory(const lldb_private::FileSpec &file_spec, uint32_t mode) override;
lldb_private::Error
SetFilePermissions (const char *path, uint32_t file_permissions) override;
GetFilePermissions(const lldb_private::FileSpec &file_spec, uint32_t &file_permissions) override;
lldb_private::Error
SetFilePermissions(const lldb_private::FileSpec &file_spec, uint32_t file_permissions) override;
bool
GetFileExists (const lldb_private::FileSpec& file_spec) override;
lldb_private::Error
Unlink (const char *path) override;
Unlink(const lldb_private::FileSpec &file_spec) override;
lldb_private::Error
LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info) override;

View File

@ -318,24 +318,17 @@ PlatformRemoteGDBServer::GetRemoteSystemArchitecture ()
return m_gdb_client.GetSystemArchitecture();
}
ConstString
FileSpec
PlatformRemoteGDBServer::GetRemoteWorkingDirectory()
{
if (IsConnected())
{
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
std::string cwd;
if (m_gdb_client.GetWorkingDir(cwd))
{
ConstString working_dir(cwd.c_str());
if (log)
log->Printf("PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'", working_dir.GetCString());
return working_dir;
}
else
{
return ConstString();
}
FileSpec working_dir;
if (m_gdb_client.GetWorkingDir(working_dir) && log)
log->Printf("PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
working_dir.GetCString());
return working_dir;
}
else
{
@ -344,7 +337,7 @@ PlatformRemoteGDBServer::GetRemoteWorkingDirectory()
}
bool
PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const ConstString &path)
PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const FileSpec &working_dir)
{
if (IsConnected())
{
@ -352,11 +345,12 @@ PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const ConstString &path)
// for use to re-read it
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", path.GetCString());
return m_gdb_client.SetWorkingDir(path.GetCString()) == 0;
log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
working_dir.GetCString());
return m_gdb_client.SetWorkingDir(working_dir) == 0;
}
else
return Platform::SetRemoteWorkingDirectory(path);
return Platform::SetRemoteWorkingDirectory(working_dir);
}
bool
@ -396,7 +390,7 @@ PlatformRemoteGDBServer::ConnectRemote (Args& args)
m_gdb_client.GetHostInfo();
// If a working directory was set prior to connecting, send it down now
if (m_working_dir)
m_gdb_client.SetWorkingDir(m_working_dir.GetCString());
m_gdb_client.SetWorkingDir(m_working_dir);
}
else
{
@ -492,13 +486,13 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
switch(file_action->GetFD())
{
case STDIN_FILENO:
m_gdb_client.SetSTDIN (file_action->GetPath());
m_gdb_client.SetSTDIN(file_action->GetFileSpec());
break;
case STDOUT_FILENO:
m_gdb_client.SetSTDOUT (file_action->GetPath());
m_gdb_client.SetSTDOUT(file_action->GetFileSpec());
break;
case STDERR_FILENO:
m_gdb_client.SetSTDERR (file_action->GetPath());
m_gdb_client.SetSTDERR(file_action->GetFileSpec());
break;
}
}
@ -506,10 +500,10 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError));
const char *working_dir = launch_info.GetWorkingDirectory();
if (working_dir && working_dir[0])
FileSpec working_dir = launch_info.GetWorkingDirectory();
if (working_dir)
{
m_gdb_client.SetWorkingDir (working_dir);
m_gdb_client.SetWorkingDir(working_dir);
}
// Send the environment and the program + arguments after we connect
@ -749,33 +743,38 @@ PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info,
}
Error
PlatformRemoteGDBServer::MakeDirectory (const char *path, uint32_t mode)
PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, uint32_t mode)
{
Error error = m_gdb_client.MakeDirectory(path,mode);
Error error = m_gdb_client.MakeDirectory(file_spec, mode);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)", path, mode, error.GetError(), error.AsCString());
log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)",
file_spec.GetCString(), mode, error.GetError(), error.AsCString());
return error;
}
Error
PlatformRemoteGDBServer::GetFilePermissions (const char *path, uint32_t &file_permissions)
PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions)
{
Error error = m_gdb_client.GetFilePermissions(path, file_permissions);
Error error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", path, file_permissions, error.GetError(), error.AsCString());
log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)",
file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString());
return error;
}
Error
PlatformRemoteGDBServer::SetFilePermissions (const char *path, uint32_t file_permissions)
PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions)
{
Error error = m_gdb_client.SetFilePermissions(path, file_permissions);
Error error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", path, file_permissions, error.GetError(), error.AsCString());
log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)",
file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString());
return error;
}
@ -831,23 +830,25 @@ PlatformRemoteGDBServer::PutFile (const FileSpec& source,
}
Error
PlatformRemoteGDBServer::CreateSymlink (const char *src, // The name of the link is in src
const char *dst) // The symlink points to dst
PlatformRemoteGDBServer::CreateSymlink(const FileSpec &src, // The name of the link is in src
const FileSpec &dst) // The symlink points to dst
{
Error error = m_gdb_client.CreateSymlink (src, dst);
Error error = m_gdb_client.CreateSymlink(src, dst);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)", src, dst, error.GetError(), error.AsCString());
log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)",
src.GetCString(), dst.GetCString(), error.GetError(), error.AsCString());
return error;
}
Error
PlatformRemoteGDBServer::Unlink (const char *path)
PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec)
{
Error error = m_gdb_client.Unlink (path);
Error error = m_gdb_client.Unlink(file_spec);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)", path, error.GetError(), error.AsCString());
log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
file_spec.GetCString(), error.GetError(), error.AsCString());
return error;
}
@ -858,14 +859,14 @@ PlatformRemoteGDBServer::GetFileExists (const FileSpec& file_spec)
}
Error
PlatformRemoteGDBServer::RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
PlatformRemoteGDBServer::RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
{
return m_gdb_client.RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
return m_gdb_client.RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
}
void

View File

@ -128,11 +128,11 @@ public:
ArchSpec
GetRemoteSystemArchitecture () override;
ConstString
FileSpec
GetRemoteWorkingDirectory() override;
bool
SetRemoteWorkingDirectory(const ConstString &path) override;
SetRemoteWorkingDirectory(const FileSpec &working_dir) override;
// Remote subclasses should override this and return a valid instance
// name if connected.
@ -155,14 +155,14 @@ public:
DisconnectRemote () override;
Error
MakeDirectory (const char *path, uint32_t file_permissions) override;
MakeDirectory(const FileSpec &file_spec, uint32_t file_permissions) override;
Error
GetFilePermissions (const char *path, uint32_t &file_permissions) override;
GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) override;
Error
SetFilePermissions (const char *path, uint32_t file_permissions) override;
SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) override;
lldb::user_id_t
OpenFile (const FileSpec& file_spec, uint32_t flags, uint32_t mode, Error &error) override;
@ -194,21 +194,21 @@ public:
uint32_t gid = UINT32_MAX) override;
Error
CreateSymlink (const char *src, const char *dst) override;
CreateSymlink(const FileSpec &src, const FileSpec &dst) override;
bool
GetFileExists (const FileSpec& file_spec) override;
Error
Unlink (const char *path) override;
Unlink(const FileSpec &path) override;
Error
RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) override; // Timeout in seconds to wait for shell program to finish
RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) override; // Timeout in seconds to wait for shell program to finish
void
CalculateTrapHandlerSymbolNames () override;

View File

@ -954,17 +954,17 @@ NativeProcessLinux::Monitor::RunMonitor(void *arg)
NativeProcessLinux::LaunchArgs::LaunchArgs(Module *module,
char const **argv,
char const **envp,
const std::string &stdin_path,
const std::string &stdout_path,
const std::string &stderr_path,
const char *working_dir,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
const ProcessLaunchInfo &launch_info)
: m_module(module),
m_argv(argv),
m_envp(envp),
m_stdin_path(stdin_path),
m_stdout_path(stdout_path),
m_stderr_path(stderr_path),
m_stdin_file_spec(stdin_file_spec),
m_stdout_file_spec(stdout_file_spec),
m_stderr_file_spec(stderr_file_spec),
m_working_dir(working_dir),
m_launch_info(launch_info)
{
@ -989,50 +989,52 @@ NativeProcessLinux::LaunchProcess (
Error error;
// Verify the working directory is valid if one was specified.
const char* working_dir = launch_info.GetWorkingDirectory ();
if (working_dir)
FileSpec working_dir{launch_info.GetWorkingDirectory()};
if (working_dir &&
(!working_dir.ResolvePath() ||
working_dir.GetFileType() != FileSpec::eFileTypeDirectory))
{
FileSpec working_dir_fs (working_dir, true);
if (!working_dir_fs || working_dir_fs.GetFileType () != FileSpec::eFileTypeDirectory)
{
error.SetErrorStringWithFormat ("No such file or directory: %s", working_dir);
return error;
}
error.SetErrorStringWithFormat ("No such file or directory: %s",
working_dir.GetCString());
return error;
}
const FileAction *file_action;
// Default of NULL will mean to use existing open file descriptors.
std::string stdin_path;
std::string stdout_path;
std::string stderr_path;
// Default of empty will mean to use existing open file descriptors.
FileSpec stdin_file_spec{};
FileSpec stdout_file_spec{};
FileSpec stderr_file_spec{};
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
if (file_action)
stdin_path = file_action->GetPath ();
stdin_file_spec = file_action->GetFileSpec();
file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
if (file_action)
stdout_path = file_action->GetPath ();
stdout_file_spec = file_action->GetFileSpec();
file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
if (file_action)
stderr_path = file_action->GetPath ();
stderr_file_spec = file_action->GetFileSpec();
if (log)
{
if (!stdin_path.empty ())
log->Printf ("NativeProcessLinux::%s setting STDIN to '%s'", __FUNCTION__, stdin_path.c_str ());
if (stdin_file_spec)
log->Printf ("NativeProcessLinux::%s setting STDIN to '%s'",
__FUNCTION__, stdin_file_spec.GetCString());
else
log->Printf ("NativeProcessLinux::%s leaving STDIN as is", __FUNCTION__);
if (!stdout_path.empty ())
log->Printf ("NativeProcessLinux::%s setting STDOUT to '%s'", __FUNCTION__, stdout_path.c_str ());
if (stdout_file_spec)
log->Printf ("NativeProcessLinux::%s setting STDOUT to '%s'",
__FUNCTION__, stdout_file_spec.GetCString());
else
log->Printf ("NativeProcessLinux::%s leaving STDOUT as is", __FUNCTION__);
if (!stderr_path.empty ())
log->Printf ("NativeProcessLinux::%s setting STDERR to '%s'", __FUNCTION__, stderr_path.c_str ());
if (stderr_file_spec)
log->Printf ("NativeProcessLinux::%s setting STDERR to '%s'",
__FUNCTION__, stderr_file_spec.GetCString());
else
log->Printf ("NativeProcessLinux::%s leaving STDERR as is", __FUNCTION__);
}
@ -1061,9 +1063,9 @@ NativeProcessLinux::LaunchProcess (
exe_module,
launch_info.GetArguments ().GetConstArgumentVector (),
launch_info.GetEnvironmentEntries ().GetConstArgumentVector (),
stdin_path,
stdout_path,
stderr_path,
stdin_file_spec,
stdout_file_spec,
stderr_file_spec,
working_dir,
launch_info,
error);
@ -1141,10 +1143,10 @@ NativeProcessLinux::LaunchInferior (
Module *module,
const char *argv[],
const char *envp[],
const std::string &stdin_path,
const std::string &stdout_path,
const std::string &stderr_path,
const char *working_dir,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
const ProcessLaunchInfo &launch_info,
Error &error)
{
@ -1154,10 +1156,12 @@ NativeProcessLinux::LaunchInferior (
SetState (eStateLaunching);
std::unique_ptr<LaunchArgs> args(
new LaunchArgs(
module, argv, envp,
stdin_path, stdout_path, stderr_path,
working_dir, launch_info));
new LaunchArgs(module, argv, envp,
stdin_file_spec,
stdout_file_spec,
stderr_file_spec,
working_dir,
launch_info));
StartMonitorThread ([&] (Error &e) { return Launch(args.get(), e); }, error);
if (!error.Success ())
@ -1226,7 +1230,7 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
const char **argv = args->m_argv;
const char **envp = args->m_envp;
const char *working_dir = args->m_working_dir;
const FileSpec working_dir = args->m_working_dir;
lldb_utility::PseudoTerminal terminal;
const size_t err_len = 1024;
@ -1286,16 +1290,16 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
}
// Dup file descriptors if needed.
if (!args->m_stdin_path.empty ())
if (!DupDescriptor(args->m_stdin_path.c_str (), STDIN_FILENO, O_RDONLY))
if (args->m_stdin_file_spec)
if (!DupDescriptor(args->m_stdin_file_spec, STDIN_FILENO, O_RDONLY))
exit(eDupStdinFailed);
if (!args->m_stdout_path.empty ())
if (!DupDescriptor(args->m_stdout_path.c_str (), STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
if (args->m_stdout_file_spec)
if (!DupDescriptor(args->m_stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
exit(eDupStdoutFailed);
if (!args->m_stderr_path.empty ())
if (!DupDescriptor(args->m_stderr_path.c_str (), STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
if (args->m_stderr_file_spec)
if (!DupDescriptor(args->m_stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
exit(eDupStderrFailed);
// Close everything besides stdin, stdout, and stderr that has no file
@ -1305,8 +1309,7 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
close(fd);
// Change working directory
if (working_dir != NULL && working_dir[0])
if (0 != ::chdir(working_dir))
if (working_dir && 0 != ::chdir(working_dir.GetCString()))
exit(eChdirFailed);
// Disable ASLR if requested.
@ -3310,9 +3313,9 @@ NativeProcessLinux::Detach(lldb::tid_t tid)
}
bool
NativeProcessLinux::DupDescriptor(const char *path, int fd, int flags)
NativeProcessLinux::DupDescriptor(const FileSpec &file_spec, int fd, int flags)
{
int target_fd = open(path, flags, 0666);
int target_fd = open(file_spec.GetCString(), flags, 0666);
if (target_fd == -1)
return false;

View File

@ -17,6 +17,7 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/lldb-types.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Target/MemoryRegionInfo.h"
@ -195,21 +196,21 @@ namespace process_linux {
LaunchArgs(Module *module,
char const **argv,
char const **envp,
const std::string &stdin_path,
const std::string &stdout_path,
const std::string &stderr_path,
const char *working_dir,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
const ProcessLaunchInfo &launch_info);
~LaunchArgs();
Module *m_module; // The executable image to launch.
char const **m_argv; // Process arguments.
char const **m_envp; // Process environment.
const std::string &m_stdin_path; // Redirect stdin if not empty.
const std::string &m_stdout_path; // Redirect stdout if not empty.
const std::string &m_stderr_path; // Redirect stderr if not empty.
const char *m_working_dir; // Working directory or NULL.
Module *m_module; // The executable image to launch.
char const **m_argv; // Process arguments.
char const **m_envp; // Process environment.
const FileSpec m_stdin_file_spec; // Redirect stdin if not empty.
const FileSpec m_stdout_file_spec; // Redirect stdout if not empty.
const FileSpec m_stderr_file_spec; // Redirect stderr if not empty.
const FileSpec m_working_dir; // Working directory or empty.
const ProcessLaunchInfo &m_launch_info;
};
@ -227,10 +228,10 @@ namespace process_linux {
Module *module,
char const *argv[],
char const *envp[],
const std::string &stdin_path,
const std::string &stdout_path,
const std::string &stderr_path,
const char *working_dir,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
const ProcessLaunchInfo &launch_info,
Error &error);
@ -252,7 +253,7 @@ namespace process_linux {
SetDefaultPtraceOpts(const lldb::pid_t);
static bool
DupDescriptor(const char *path, int fd, int flags);
DupDescriptor(const FileSpec &file_spec, int fd, int flags);
static void *
MonitorThread(void *baton);

View File

@ -1185,18 +1185,18 @@ ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
lldb_private::Module *module,
char const **argv,
char const **envp,
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
const char *working_dir,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
const lldb_private::ProcessLaunchInfo &launch_info)
: OperationArgs(monitor),
m_module(module),
m_argv(argv),
m_envp(envp),
m_stdin_path(stdin_path),
m_stdout_path(stdout_path),
m_stderr_path(stderr_path),
m_stdin_file_spec(stdin_file_spec),
m_stdout_file_spec(stdout_file_spec),
m_stderr_file_spec(stderr_file_spec),
m_working_dir(working_dir),
m_launch_info(launch_info)
{
@ -1228,10 +1228,10 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
Module *module,
const char *argv[],
const char *envp[],
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
const char *working_dir,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir,
const lldb_private::ProcessLaunchInfo &launch_info,
lldb_private::Error &error)
: m_process(static_cast<ProcessLinux *>(process)),
@ -1242,8 +1242,11 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
m_operation(0)
{
std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp,
stdin_path, stdout_path, stderr_path,
working_dir, launch_info));
stdin_file_spec,
stdout_file_spec,
stderr_file_spec,
working_dir,
launch_info));
sem_init(&m_operation_pending, 0, 0);
sem_init(&m_operation_done, 0, 0);
@ -1378,10 +1381,10 @@ ProcessMonitor::Launch(LaunchArgs *args)
ProcessLinux &process = monitor->GetProcess();
const char **argv = args->m_argv;
const char **envp = args->m_envp;
const char *stdin_path = args->m_stdin_path;
const char *stdout_path = args->m_stdout_path;
const char *stderr_path = args->m_stderr_path;
const char *working_dir = args->m_working_dir;
const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
const FileSpec &working_dir = args->m_working_dir;
lldb_utility::PseudoTerminal terminal;
const size_t err_len = 1024;
@ -1436,22 +1439,21 @@ ProcessMonitor::Launch(LaunchArgs *args)
//
// FIXME: If two or more of the paths are the same we needlessly open
// the same file multiple times.
if (stdin_path != NULL && stdin_path[0])
if (!DupDescriptor(stdin_path, STDIN_FILENO, O_RDONLY))
if (stdin_file_spec)
if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
exit(eDupStdinFailed);
if (stdout_path != NULL && stdout_path[0])
if (!DupDescriptor(stdout_path, STDOUT_FILENO, O_WRONLY | O_CREAT))
if (stdout_file_spec)
if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
exit(eDupStdoutFailed);
if (stderr_path != NULL && stderr_path[0])
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
if (stderr_file_spec)
if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
exit(eDupStderrFailed);
// Change working directory
if (working_dir != NULL && working_dir[0])
if (0 != ::chdir(working_dir))
exit(eChdirFailed);
if (working_dir && 0 != ::chdir(working_dir.GetCString()))
exit(eChdirFailed);
// Disable ASLR if requested.
if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR))
@ -2402,9 +2404,9 @@ ProcessMonitor::Detach(lldb::tid_t tid)
}
bool
ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)
ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd, int flags)
{
int target_fd = open(path, flags, 0666);
int target_fd = open(file_spec.GetCString(), flags, 0666);
if (target_fd == -1)
return false;

View File

@ -17,6 +17,7 @@
// C++ Includes
// Other libraries and framework includes
#include "lldb/lldb-types.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Mutex.h"
@ -58,10 +59,10 @@ public:
lldb_private::Module *module,
char const *argv[],
char const *envp[],
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
const char *working_dir,
const lldb_private::FileSpec &stdin_file_spec,
const lldb_private::FileSpec &stdout_file_spec,
const lldb_private::FileSpec &stderr_file_spec,
const lldb_private::FileSpec &working_dir,
const lldb_private::ProcessLaunchInfo &launch_info,
lldb_private::Error &error);
@ -251,21 +252,21 @@ private:
lldb_private::Module *module,
char const **argv,
char const **envp,
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
const char *working_dir,
const lldb_private::FileSpec &stdin_file_spec,
const lldb_private::FileSpec &stdout_file_spec,
const lldb_private::FileSpec &stderr_file_spec,
const lldb_private::FileSpec &working_dir,
const lldb_private::ProcessLaunchInfo &launch_info);
~LaunchArgs();
lldb_private::Module *m_module; // The executable image to launch.
char const **m_argv; // Process arguments.
char const **m_envp; // Process environment.
const char *m_stdin_path; // Redirect stdin or NULL.
const char *m_stdout_path; // Redirect stdout or NULL.
const char *m_stderr_path; // Redirect stderr or NULL.
const char *m_working_dir; // Working directory or NULL.
lldb_private::Module *m_module; // The executable image to launch.
char const **m_argv; // Process arguments.
char const **m_envp; // Process environment.
const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
const lldb_private::FileSpec m_stdout_file_spec; // Redirect stdout or empty.
const lldb_private::FileSpec m_stderr_file_spec; // Redirect stderr or empty.
const lldb_private::FileSpec m_working_dir; // Working directory or empty.
const lldb_private::ProcessLaunchInfo &m_launch_info;
};
@ -304,7 +305,7 @@ private:
ServeOperation(OperationArgs *args);
static bool
DupDescriptor(const char *path, int fd, int flags);
DupDescriptor(const lldb_private::FileSpec &file_spec, int fd, int flags);
static bool
MonitorCallback(void *callback_baton,

View File

@ -50,9 +50,9 @@ ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener, UnixSignalsSP &un
{
// FIXME: Putting this code in the ctor and saving the byte order in a
// member variable is a hack to avoid const qual issues in GetByteOrder.
lldb::ModuleSP module = GetTarget().GetExecutableModule();
if (module && module->GetObjectFile())
m_byte_order = module->GetObjectFile()->GetByteOrder();
lldb::ModuleSP module = GetTarget().GetExecutableModule();
if (module && module->GetObjectFile())
m_byte_order = module->GetObjectFile()->GetByteOrder();
}
ProcessPOSIX::~ProcessPOSIX()
@ -138,27 +138,24 @@ ProcessPOSIX::WillLaunch(Module* module)
return error;
}
const char *
ProcessPOSIX::GetFilePath(const lldb_private::FileAction *file_action, const char *default_path,
const char *dbg_pts_path)
FileSpec
ProcessPOSIX::GetFileSpec(const lldb_private::FileAction *file_action,
const FileSpec &default_file_spec,
const FileSpec &dbg_pts_file_spec)
{
const char *path = NULL;
FileSpec file_spec{};
if (file_action)
if (file_action && file_action->GetAction() == FileAction::eFileActionOpen)
{
if (file_action->GetAction() == FileAction::eFileActionOpen)
{
path = file_action->GetPath();
// By default the stdio paths passed in will be pseudo-terminal
// (/dev/pts). If so, convert to using a different default path
// instead to redirect I/O to the debugger console. This should
// also handle user overrides to /dev/null or a different file.
if (!path || (dbg_pts_path &&
::strncmp(path, dbg_pts_path, ::strlen(dbg_pts_path)) == 0))
path = default_path;
}
file_spec = file_action->GetFileSpec();
// By default the stdio paths passed in will be pseudo-terminal
// (/dev/pts). If so, convert to using a different default path
// instead to redirect I/O to the debugger console. This should
// also handle user overrides to /dev/null or a different file.
if (!file_spec || file_spec == dbg_pts_file_spec)
file_spec = default_file_spec;
}
return path;
return file_spec;
}
Error
@ -168,46 +165,46 @@ ProcessPOSIX::DoLaunch (Module *module,
Error error;
assert(m_monitor == NULL);
const char* working_dir = launch_info.GetWorkingDirectory();
if (working_dir) {
FileSpec WorkingDir(working_dir, true);
if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
{
error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
return error;
}
FileSpec working_dir = launch_info.GetWorkingDirectory();
if (working_dir &&
(!working_dir.ResolvePath() ||
working_dir.GetFileType() != FileSpec::eFileTypeDirectory))
{
error.SetErrorStringWithFormat("No such file or directory: %s",
working_dir.GetCString());
return error;
}
SetPrivateState(eStateLaunching);
const lldb_private::FileAction *file_action;
// Default of NULL will mean to use existing open file descriptors
const char *stdin_path = NULL;
const char *stdout_path = NULL;
const char *stderr_path = NULL;
// Default of empty will mean to use existing open file descriptors
FileSpec stdin_file_spec{};
FileSpec stdout_file_spec{};
FileSpec stderr_file_spec{};
const char * dbg_pts_path = launch_info.GetPTY().GetSlaveName(NULL,0);
const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL,0), false};
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
stdin_path = GetFilePath(file_action, stdin_path, dbg_pts_path);
stdin_file_spec = GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
stdout_path = GetFilePath(file_action, stdout_path, dbg_pts_path);
stdout_file_spec = GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
stderr_path = GetFilePath(file_action, stderr_path, dbg_pts_path);
stderr_file_spec = GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
m_monitor = new ProcessMonitor (this,
module,
launch_info.GetArguments().GetConstArgumentVector(),
launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
stdin_path,
stdout_path,
stderr_path,
working_dir,
launch_info,
error);
m_monitor = new ProcessMonitor(this,
module,
launch_info.GetArguments().GetConstArgumentVector(),
launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
stdin_file_spec,
stdout_file_spec,
stderr_file_spec,
working_dir,
launch_info,
error);
m_module = module;

View File

@ -151,8 +151,10 @@ public:
ProcessMonitor &
GetMonitor() { assert(m_monitor); return *m_monitor; }
const char *GetFilePath(const lldb_private::FileAction *file_action, const char *default_path,
const char *dbg_pts_path);
lldb_private::FileSpec
GetFileSpec(const lldb_private::FileAction *file_action,
const lldb_private::FileSpec &default_file_spec,
const lldb_private::FileSpec &dbg_pts_file_spec);
/// Stops all threads in the process.
/// The \p stop_tid parameter indicates the thread which initiated the stop.

View File

@ -1325,7 +1325,7 @@ GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &laun
const char *arg = NULL;
const Args &launch_args = launch_info.GetArguments();
if (exe_file)
exe_path = exe_file.GetPath();
exe_path = exe_file.GetPath(false);
else
{
arg = launch_args.GetArgumentAtIndex(0);
@ -2221,13 +2221,14 @@ GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after
}
int
GDBRemoteCommunicationClient::SetSTDIN (char const *path)
GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec)
{
if (path && path[0])
if (file_spec)
{
std::string path{file_spec.GetPath(false)};
StreamString packet;
packet.PutCString("QSetSTDIN:");
packet.PutBytesAsRawHex8(path, strlen(path));
packet.PutCStringAsRawHex8(path.c_str());
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
@ -2243,14 +2244,15 @@ GDBRemoteCommunicationClient::SetSTDIN (char const *path)
}
int
GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec)
{
if (path && path[0])
if (file_spec)
{
std::string path{file_spec.GetPath(false)};
StreamString packet;
packet.PutCString("QSetSTDOUT:");
packet.PutBytesAsRawHex8(path, strlen(path));
packet.PutCStringAsRawHex8(path.c_str());
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
@ -2265,14 +2267,15 @@ GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
}
int
GDBRemoteCommunicationClient::SetSTDERR (char const *path)
GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec)
{
if (path && path[0])
if (file_spec)
{
std::string path{file_spec.GetPath(false)};
StreamString packet;
packet.PutCString("QSetSTDERR:");
packet.PutBytesAsRawHex8(path, strlen(path));
packet.PutCStringAsRawHex8(path.c_str());
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
@ -2287,7 +2290,7 @@ GDBRemoteCommunicationClient::SetSTDERR (char const *path)
}
bool
GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd)
GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir)
{
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
@ -2296,21 +2299,24 @@ GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd)
return false;
if (response.IsErrorResponse())
return false;
response.GetHexByteString (cwd);
std::string cwd;
response.GetHexByteString(cwd);
working_dir.SetFile(cwd, false);
return !cwd.empty();
}
return false;
}
int
GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir)
{
if (path && path[0])
if (working_dir)
{
std::string path{working_dir.GetPath(false)};
StreamString packet;
packet.PutCString("QSetWorkingDir:");
packet.PutBytesAsRawHex8(path, strlen(path));
packet.PutCStringAsRawHex8(path.c_str());
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
@ -3262,22 +3268,23 @@ GDBRemoteCommunicationClient::GetShlibInfoAddr()
}
lldb_private::Error
GDBRemoteCommunicationClient::RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
GDBRemoteCommunicationClient::RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
{
lldb_private::StreamString stream;
stream.PutCString("qPlatform_shell:");
stream.PutBytesAsRawHex8(command, strlen(command));
stream.PutChar(',');
stream.PutHex32(timeout_sec);
if (working_dir && *working_dir)
if (working_dir)
{
std::string path{working_dir.GetPath(false)};
stream.PutChar(',');
stream.PutBytesAsRawHex8(working_dir, strlen(working_dir));
stream.PutCStringAsRawHex8(path.c_str());
}
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
@ -3310,14 +3317,15 @@ GDBRemoteCommunicationClient::RunShellCommand (const char *command, //
}
Error
GDBRemoteCommunicationClient::MakeDirectory (const char *path,
uint32_t file_permissions)
GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
uint32_t file_permissions)
{
std::string path{file_spec.GetPath(false)};
lldb_private::StreamString stream;
stream.PutCString("qPlatform_mkdir:");
stream.PutHex32(file_permissions);
stream.PutChar(',');
stream.PutBytesAsRawHex8(path, strlen(path));
stream.PutCStringAsRawHex8(path.c_str());
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
@ -3332,14 +3340,15 @@ GDBRemoteCommunicationClient::MakeDirectory (const char *path,
}
Error
GDBRemoteCommunicationClient::SetFilePermissions (const char *path,
uint32_t file_permissions)
GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions)
{
std::string path{file_spec.GetPath(false)};
lldb_private::StreamString stream;
stream.PutCString("qPlatform_chmod:");
stream.PutHex32(file_permissions);
stream.PutChar(',');
stream.PutBytesAsRawHex8(path, strlen(path));
stream.PutCStringAsRawHex8(path.c_str());
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
@ -3382,9 +3391,9 @@ GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
mode_t mode,
Error &error)
{
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
stream.PutCString("vFile:open:");
std::string path (file_spec.GetPath(false));
if (path.empty())
return UINT64_MAX;
stream.PutCStringAsRawHex8(path.c_str());
@ -3422,9 +3431,9 @@ GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
lldb::user_id_t
GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
{
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
stream.PutCString("vFile:size:");
std::string path (file_spec.GetPath());
stream.PutCStringAsRawHex8(path.c_str());
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
@ -3440,12 +3449,14 @@ GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_sp
}
Error
GDBRemoteCommunicationClient::GetFilePermissions(const char *path, uint32_t &file_permissions)
GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions)
{
std::string path{file_spec.GetPath(false)};
Error error;
lldb_private::StreamString stream;
stream.PutCString("vFile:mode:");
stream.PutCStringAsRawHex8(path);
stream.PutCStringAsRawHex8(path.c_str());
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
@ -3564,16 +3575,18 @@ GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
}
Error
GDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst)
GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, const FileSpec &dst)
{
std::string src_path{src.GetPath(false)},
dst_path{dst.GetPath(false)};
Error error;
lldb_private::StreamGDBRemote stream;
stream.PutCString("vFile:symlink:");
// the unix symlink() command reverses its parameters where the dst if first,
// so we follow suit here
stream.PutCStringAsRawHex8(dst);
stream.PutCStringAsRawHex8(dst_path.c_str());
stream.PutChar(',');
stream.PutCStringAsRawHex8(src);
stream.PutCStringAsRawHex8(src_path.c_str());
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
@ -3607,14 +3620,15 @@ GDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst)
}
Error
GDBRemoteCommunicationClient::Unlink (const char *path)
GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec)
{
std::string path{file_spec.GetPath(false)};
Error error;
lldb_private::StreamGDBRemote stream;
stream.PutCString("vFile:unlink:");
// the unix symlink() command reverses its parameters where the dst if first,
// so we follow suit here
stream.PutCStringAsRawHex8(path);
stream.PutCStringAsRawHex8(path.c_str());
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
@ -3651,9 +3665,9 @@ GDBRemoteCommunicationClient::Unlink (const char *path)
bool
GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
{
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
stream.PutCString("vFile:exists:");
std::string path (file_spec.GetPath());
stream.PutCStringAsRawHex8(path.c_str());
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
@ -3675,9 +3689,9 @@ GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_s
uint64_t &high,
uint64_t &low)
{
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
stream.PutCString("vFile:MD5:");
std::string path (file_spec.GetPath());
stream.PutCStringAsRawHex8(path.c_str());
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
@ -3874,7 +3888,7 @@ GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec,
packet.PutCStringAsRawHex8(module_path.c_str());
packet.PutCString(";");
const auto& triple = arch_spec.GetTriple().getTriple();
packet.PutBytesAsRawHex8(triple.c_str(), triple.size());
packet.PutCStringAsRawHex8(triple.c_str());
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success)

View File

@ -205,11 +205,11 @@ public:
/// Zero if the for success, or an error code for failure.
//------------------------------------------------------------------
int
SetSTDIN (char const *path);
SetSTDIN(const FileSpec &file_spec);
int
SetSTDOUT (char const *path);
SetSTDOUT(const FileSpec &file_spec);
int
SetSTDERR (char const *path);
SetSTDERR(const FileSpec &file_spec);
//------------------------------------------------------------------
/// Sets the disable ASLR flag to \a enable for a process that will
@ -243,27 +243,27 @@ public:
/// implements the platform, it will change the current working
/// directory for the platform process.
///
/// @param[in] path
/// @param[in] working_dir
/// The path to a directory to use when launching our process
///
/// @return
/// Zero if the for success, or an error code for failure.
//------------------------------------------------------------------
int
SetWorkingDir (char const *path);
SetWorkingDir(const FileSpec &working_dir);
//------------------------------------------------------------------
/// Gets the current working directory of a remote platform GDB
/// server.
///
/// @param[out] cwd
/// @param[out] working_dir
/// The current working directory on the remote platform.
///
/// @return
/// Boolean for success
//------------------------------------------------------------------
bool
GetWorkingDir (std::string &cwd);
GetWorkingDir(FileSpec &working_dir);
lldb::addr_t
AllocateMemory (size_t size, uint32_t permissions);
@ -466,10 +466,10 @@ public:
GetFileSize (const FileSpec& file_spec);
Error
GetFilePermissions(const char *path, uint32_t &file_permissions);
GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions);
Error
SetFilePermissions(const char *path, uint32_t file_permissions);
SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions);
uint64_t
ReadFile (lldb::user_id_t fd,
@ -486,26 +486,26 @@ public:
Error &error);
Error
CreateSymlink (const char *src,
const char *dst);
CreateSymlink(const FileSpec &src,
const FileSpec &dst);
Error
Unlink (const char *path);
Unlink(const FileSpec &file_spec);
Error
MakeDirectory (const char *path, uint32_t mode);
MakeDirectory(const FileSpec &file_spec, uint32_t mode);
bool
GetFileExists (const FileSpec& file_spec);
Error
RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
bool
CalculateMD5 (const FileSpec& file_spec, uint64_t &high, uint64_t &low);

View File

@ -584,8 +584,8 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote
{
mode_t mode = packet.GetHexMaxU32(false, 0600);
Error error;
const FileSpec path_spec(path.c_str(), true);
int fd = ::open (path_spec.GetPath().c_str(), flags, mode);
const FileSpec path_spec{path, true};
int fd = ::open(path_spec.GetCString(), flags, mode);
const int save_errno = fd == -1 ? errno : 0;
StreamString response;
response.PutChar('F');
@ -734,7 +734,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode (StringExtractorGDBRemote
if (!path.empty())
{
Error error;
const uint32_t mode = File::GetPermissions(path.c_str(), error);
const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
StreamString response;
response.Printf("F%u", mode);
if (mode == 0 || error.Fail())
@ -773,7 +773,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink (StringExtractorGDBRemo
packet.GetHexByteStringTerminatedBy(dst, ',');
packet.GetChar(); // Skip ',' char
packet.GetHexByteString(src);
Error error = FileSystem::Symlink(src.c_str(), dst.c_str());
Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
StreamString response;
response.Printf("F%u,%u", error.GetError(), error.GetError());
return SendPacketNoLock(response.GetData(), response.GetSize());
@ -785,7 +785,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_unlink (StringExtractorGDBRemot
packet.SetFilePos(::strlen("vFile:unlink:"));
std::string path;
packet.GetHexByteString(path);
Error error = FileSystem::Unlink(path.c_str());
Error error = FileSystem::Unlink(FileSpec{path, true});
StreamString response;
response.Printf("F%u,%u", error.GetError(), error.GetError());
return SendPacketNoLock(response.GetData(), response.GetSize());
@ -810,7 +810,7 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell (StringExtractorGDBRe
int status, signo;
std::string output;
Error err = Host::RunShellCommand(path.c_str(),
working_dir.empty() ? NULL : working_dir.c_str(),
FileSpec{working_dir, true},
&status, &signo, &output, timeout);
StreamGDBRemote response;
if (err.Fail())
@ -875,8 +875,8 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir (StringExtractorGDBRe
{
std::string path;
packet.GetHexByteString(path);
Error error = FileSystem::MakeDirectory(path.c_str(), mode);
Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
StreamGDBRemote response;
response.Printf("F%u", error.GetError());
@ -895,7 +895,7 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod (StringExtractorGDBRe
{
std::string path;
packet.GetHexByteString(path);
Error error = FileSystem::SetFilePermissions(path.c_str(), mode);
Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
StreamGDBRemote response;
response.Printf("F%u", error.GetError());
@ -968,7 +968,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN (StringExtractorGDBRemote &
packet.GetHexByteString(path);
const bool read = false;
const bool write = true;
if (file_action.Open(STDIN_FILENO, path.c_str(), read, write))
if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write))
{
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse ();
@ -985,7 +985,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT (StringExtractorGDBRemote
packet.GetHexByteString(path);
const bool read = true;
const bool write = false;
if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write))
if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write))
{
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse ();
@ -1002,7 +1002,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR (StringExtractorGDBRemote
packet.GetHexByteString(path);
const bool read = true;
const bool write = false;
if (file_action.Open(STDERR_FILENO, path.c_str(), read, write))
if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write))
{
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse ();
@ -1217,7 +1217,7 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote
response.PutChar(';');
response.PutCString("file_path:");
response.PutCStringAsRawHex8(module_path_spec.GetPath().c_str());
response.PutCStringAsRawHex8(module_path_spec.GetCString());
response.PutChar(';');
response.PutCString("file_offset:");
response.PutHex64(file_offset);
@ -1241,7 +1241,7 @@ GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInst
proc_info.GetEffectiveUserID(),
proc_info.GetEffectiveGroupID());
response.PutCString ("name:");
response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str());
response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
response.PutChar(';');
const ArchSpec &proc_arch = proc_info.GetArchitecture();
if (proc_arch.IsValid())

View File

@ -950,18 +950,18 @@ GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir (StringExtractorGDBRemot
packet.SetFilePos (::strlen ("QSetWorkingDir:"));
std::string path;
packet.GetHexByteString (path);
m_process_launch_info.SwapWorkingDirectory (path);
m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
return SendOKResponse ();
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
{
const char *working_dir = m_process_launch_info.GetWorkingDirectory();
if (working_dir && working_dir[0])
FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
if (working_dir)
{
StreamString response;
response.PutBytesAsRawHex8(working_dir, strlen(working_dir));
response.PutCStringAsRawHex8(working_dir.GetCString());
return SendPacketNoLock(response.GetData(), response.GetSize());
}

View File

@ -878,45 +878,45 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
log->Printf ("ProcessGDBRemote::%s() entered", __FUNCTION__);
uint32_t launch_flags = launch_info.GetFlags().Get();
const char *stdin_path = NULL;
const char *stdout_path = NULL;
const char *stderr_path = NULL;
const char *working_dir = launch_info.GetWorkingDirectory();
FileSpec stdin_file_spec{};
FileSpec stdout_file_spec{};
FileSpec stderr_file_spec{};
FileSpec working_dir = launch_info.GetWorkingDirectory();
const FileAction *file_action;
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
if (file_action)
{
if (file_action->GetAction() == FileAction::eFileActionOpen)
stdin_path = file_action->GetPath();
stdin_file_spec = file_action->GetFileSpec();
}
file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
if (file_action)
{
if (file_action->GetAction() == FileAction::eFileActionOpen)
stdout_path = file_action->GetPath();
stdout_file_spec = file_action->GetFileSpec();
}
file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
if (file_action)
{
if (file_action->GetAction() == FileAction::eFileActionOpen)
stderr_path = file_action->GetPath();
stderr_file_spec = file_action->GetFileSpec();
}
if (log)
{
if (stdin_path || stdout_path || stderr_path)
if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
log->Printf ("ProcessGDBRemote::%s provided with STDIO paths via launch_info: stdin=%s, stdout=%s, stderr=%s",
__FUNCTION__,
stdin_path ? stdin_path : "<null>",
stdout_path ? stdout_path : "<null>",
stderr_path ? stderr_path : "<null>");
stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
else
log->Printf ("ProcessGDBRemote::%s no STDIO paths given via launch_info", __FUNCTION__);
}
const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
if (stdin_path || disable_stdio)
if (stdin_file_spec || disable_stdio)
{
// the inferior will be reading stdin from the specified file
// or stdio is completely disabled
@ -949,12 +949,12 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
if (disable_stdio)
{
// set to /dev/null unless redirected to a file above
if (!stdin_path)
stdin_path = "/dev/null";
if (!stdout_path)
stdout_path = "/dev/null";
if (!stderr_path)
stderr_path = "/dev/null";
if (!stdin_file_spec)
stdin_file_spec.SetFile("/dev/null", false);
if (!stdout_file_spec)
stdout_file_spec.SetFile("/dev/null", false);
if (!stderr_file_spec)
stderr_file_spec.SetFile("/dev/null", false);
}
else if (platform_sp && platform_sp->IsHost())
{
@ -962,42 +962,41 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
// a pseudo terminal to instead of relying on the 'O' packets for stdio
// since 'O' packets can really slow down debugging if the inferior
// does a lot of output.
const char *slave_name = NULL;
if (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL)
if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
{
if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
slave_name = pty.GetSlaveName (NULL, 0);
FileSpec slave_name{pty.GetSlaveName(NULL, 0), false};
if (!stdin_file_spec)
stdin_file_spec = slave_name;
if (!stdout_file_spec)
stdout_file_spec = slave_name;
if (!stderr_file_spec)
stderr_file_spec = slave_name;
}
if (stdin_path == NULL)
stdin_path = slave_name;
if (stdout_path == NULL)
stdout_path = slave_name;
if (stderr_path == NULL)
stderr_path = slave_name;
if (log)
log->Printf ("ProcessGDBRemote::%s adjusted STDIO paths for local platform (IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
__FUNCTION__,
stdin_path ? stdin_path : "<null>",
stdout_path ? stdout_path : "<null>",
stderr_path ? stderr_path : "<null>");
stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
}
if (log)
log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stderr=%s",
__FUNCTION__,
stdin_path ? stdin_path : "<null>",
stdout_path ? stdout_path : "<null>",
stderr_path ? stderr_path : "<null>");
stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
if (stdin_path)
m_gdb_comm.SetSTDIN (stdin_path);
if (stdout_path)
m_gdb_comm.SetSTDOUT (stdout_path);
if (stderr_path)
m_gdb_comm.SetSTDERR (stderr_path);
if (stdin_file_spec)
m_gdb_comm.SetSTDIN(stdin_file_spec);
if (stdout_file_spec)
m_gdb_comm.SetSTDOUT(stdout_file_spec);
if (stderr_file_spec)
m_gdb_comm.SetSTDERR(stderr_file_spec);
m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR);
m_gdb_comm.SetDetachOnError (launch_flags & eLaunchFlagDetachOnError);
@ -1008,7 +1007,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
if (launch_event_data != NULL && *launch_event_data != '\0')
m_gdb_comm.SendLaunchEventDataPacket (launch_event_data);
if (working_dir && working_dir[0])
if (working_dir)
{
m_gdb_comm.SetWorkingDir (working_dir);
}

View File

@ -26,7 +26,7 @@ FileAction::FileAction() :
m_action(eFileActionNone),
m_fd(-1),
m_arg(-1),
m_path()
m_file_spec()
{
}
@ -36,21 +36,25 @@ FileAction::Clear()
m_action = eFileActionNone;
m_fd = -1;
m_arg = -1;
m_path.clear();
m_file_spec.Clear();
}
const char *
FileAction::GetPath() const
{
if (m_path.empty())
return NULL;
return m_path.c_str();
return m_file_spec.GetCString();
}
const FileSpec &
FileAction::GetFileSpec() const
{
return m_file_spec;
}
bool
FileAction::Open(int fd, const char *path, bool read, bool write)
FileAction::Open(int fd, const FileSpec &file_spec, bool read, bool write)
{
if ((read || write) && fd >= 0 && path && path[0])
if ((read || write) && fd >= 0 && file_spec)
{
m_action = eFileActionOpen;
m_fd = fd;
@ -60,7 +64,7 @@ FileAction::Open(int fd, const char *path, bool read, bool write)
m_arg = O_NOCTTY | O_RDONLY;
else
m_arg = O_NOCTTY | O_CREAT | O_WRONLY;
m_path.assign(path);
m_file_spec = file_spec;
return true;
}
else
@ -111,7 +115,8 @@ FileAction::Dump(Stream &stream) const
stream.PutCString("no action");
break;
case eFileActionOpen:
stream.Printf("open fd %d with '%s', OFLAGS = 0x%x", m_fd, m_path.c_str(), m_arg);
stream.Printf("open fd %d with '%s', OFLAGS = 0x%x",
m_fd, m_file_spec.GetCString(), m_arg);
break;
}
}

View File

@ -610,16 +610,16 @@ Platform::AddClangModuleCompilationOptions (Target *target, std::vector<std::str
}
ConstString
FileSpec
Platform::GetWorkingDirectory ()
{
if (IsHost())
{
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)))
return ConstString(cwd);
return FileSpec{cwd, true};
else
return ConstString();
return FileSpec{};
}
else
{
@ -658,11 +658,11 @@ RecurseCopy_Callback (void *baton,
FileSpec dst_dir = rc_baton->dst;
if (!dst_dir.GetFilename())
dst_dir.GetFilename() = src.GetLastPathComponent();
std::string dst_dir_path (dst_dir.GetPath());
Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault);
Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir, lldb::eFilePermissionsDirectoryDefault);
if (error.Fail())
{
rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str());
rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end",
dst_dir.GetCString());
return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
}
@ -690,15 +690,15 @@ RecurseCopy_Callback (void *baton,
FileSpec dst_file = rc_baton->dst;
if (!dst_file.GetFilename())
dst_file.GetFilename() = src.GetFilename();
char buf[PATH_MAX];
rc_baton->error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
FileSpec src_resolved;
rc_baton->error = FileSystem::Readlink(src, src_resolved);
if (rc_baton->error.Fail())
return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf);
rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file, src_resolved);
if (rc_baton->error.Fail())
return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
@ -745,7 +745,7 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
if (!fixed_dst.GetFilename())
fixed_dst.GetFilename() = src.GetFilename();
ConstString working_dir = GetWorkingDirectory();
FileSpec working_dir = GetWorkingDirectory();
if (dst)
{
@ -765,8 +765,8 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
std::string path;
if (working_dir)
{
relative_spec.SetFile(working_dir.GetCString(), false);
relative_spec.AppendPathComponent(dst.GetPath().c_str());
relative_spec = working_dir;
relative_spec.AppendPathComponent(dst.GetPath());
fixed_dst.GetDirectory() = relative_spec.GetDirectory();
}
else
@ -780,7 +780,7 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
{
if (working_dir)
{
fixed_dst.GetDirectory() = working_dir;
fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
}
else
{
@ -793,7 +793,7 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
{
if (working_dir)
{
fixed_dst.GetDirectory() = working_dir;
fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
}
else
{
@ -816,18 +816,17 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
case FileSpec::eFileTypeDirectory:
{
if (GetFileExists (fixed_dst))
Unlink (fixed_dst.GetPath().c_str());
Unlink(fixed_dst);
uint32_t permissions = src.GetPermissions();
if (permissions == 0)
permissions = eFilePermissionsDirectoryDefault;
std::string dst_dir_path(fixed_dst.GetPath());
error = MakeDirectory(dst_dir_path.c_str(), permissions);
error = MakeDirectory(fixed_dst, permissions);
if (error.Success())
{
// Make a filespec that only fills in the directory of a FileSpec so
// when we enumerate we can quickly fill in the filename for dst copies
FileSpec recurse_dst;
recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str());
recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString());
std::string src_dir_path (src.GetPath());
RecurseCopyBaton baton = { recurse_dst, this, Error() };
FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
@ -838,18 +837,18 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
case FileSpec::eFileTypeRegular:
if (GetFileExists (fixed_dst))
Unlink (fixed_dst.GetPath().c_str());
Unlink(fixed_dst);
error = PutFile(src, fixed_dst);
break;
case FileSpec::eFileTypeSymbolicLink:
{
if (GetFileExists (fixed_dst))
Unlink (fixed_dst.GetPath().c_str());
char buf[PATH_MAX];
error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
Unlink(fixed_dst);
FileSpec src_resolved;
error = FileSystem::Readlink(src, src_resolved);
if (error.Success())
error = CreateSymlink(dst.GetPath().c_str(), buf);
error = CreateSymlink(dst, src_resolved);
}
break;
case FileSpec::eFileTypePipe:
@ -869,16 +868,17 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
}
bool
Platform::SetWorkingDirectory (const ConstString &path)
Platform::SetWorkingDirectory(const FileSpec &file_spec)
{
if (IsHost())
{
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf("Platform::SetWorkingDirectory('%s')", path.GetCString());
if (path)
log->Printf("Platform::SetWorkingDirectory('%s')",
file_spec.GetCString());
if (file_spec)
{
if (chdir(path.GetCString()) == 0)
if (::chdir(file_spec.GetCString()) == 0)
return true;
}
return false;
@ -886,15 +886,15 @@ Platform::SetWorkingDirectory (const ConstString &path)
else
{
m_working_dir.Clear();
return SetRemoteWorkingDirectory(path);
return SetRemoteWorkingDirectory(file_spec);
}
}
Error
Platform::MakeDirectory (const char *path, uint32_t permissions)
Platform::MakeDirectory(const FileSpec &file_spec, uint32_t permissions)
{
if (IsHost())
return FileSystem::MakeDirectory(path, permissions);
return FileSystem::MakeDirectory(file_spec, permissions);
else
{
Error error;
@ -904,10 +904,10 @@ Platform::MakeDirectory (const char *path, uint32_t permissions)
}
Error
Platform::GetFilePermissions (const char *path, uint32_t &file_permissions)
Platform::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
{
if (IsHost())
return FileSystem::GetFilePermissions(path, file_permissions);
return FileSystem::GetFilePermissions(file_spec, file_permissions);
else
{
Error error;
@ -917,10 +917,10 @@ Platform::GetFilePermissions (const char *path, uint32_t &file_permissions)
}
Error
Platform::SetFilePermissions (const char *path, uint32_t file_permissions)
Platform::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
{
if (IsHost())
return FileSystem::SetFilePermissions(path, file_permissions);
return FileSystem::SetFilePermissions(file_spec, file_permissions);
else
{
Error error;
@ -947,12 +947,13 @@ Platform::GetHostname ()
}
bool
Platform::SetRemoteWorkingDirectory(const ConstString &path)
Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir)
{
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
log->Printf("Platform::SetRemoteWorkingDirectory('%s')", path.GetCString());
m_working_dir = path;
log->Printf("Platform::SetRemoteWorkingDirectory('%s')",
working_dir.GetCString());
m_working_dir = working_dir;
return true;
}
@ -1470,29 +1471,29 @@ Platform::PutFile (const FileSpec& source,
}
Error
Platform::GetFile (const FileSpec& source,
const FileSpec& destination)
Platform::GetFile(const FileSpec &source,
const FileSpec &destination)
{
Error error("unimplemented");
return error;
}
Error
Platform::CreateSymlink (const char *src, // The name of the link is in src
const char *dst)// The symlink points to dst
Platform::CreateSymlink(const FileSpec &src, // The name of the link is in src
const FileSpec &dst) // The symlink points to dst
{
Error error("unimplemented");
return error;
}
bool
Platform::GetFileExists (const lldb_private::FileSpec& file_spec)
Platform::GetFileExists(const lldb_private::FileSpec &file_spec)
{
return false;
}
Error
Platform::Unlink (const char *path)
Platform::Unlink(const FileSpec &path)
{
Error error("unimplemented");
return error;
@ -1510,12 +1511,12 @@ Platform::ConvertMmapFlagsToPlatform(unsigned flags)
}
lldb_private::Error
Platform::RunShellCommand (const char *command, // Shouldn't be NULL
const char *working_dir, // Pass NULL to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
Platform::RunShellCommand(const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
std::string *command_output, // Pass NULL if you don't want the command output
uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
{
if (IsHost())
return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);

View File

@ -432,7 +432,7 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'i': // STDIN for read only
{
FileAction action;
if (action.Open (STDIN_FILENO, option_arg, true, false))
if (action.Open(STDIN_FILENO, FileSpec{option_arg, false}, true, false))
launch_info.AppendFileAction (action);
break;
}
@ -440,7 +440,7 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'o': // Open STDOUT for write only
{
FileAction action;
if (action.Open (STDOUT_FILENO, option_arg, false, true))
if (action.Open(STDOUT_FILENO, FileSpec{option_arg, false}, false, true))
launch_info.AppendFileAction (action);
break;
}
@ -448,7 +448,7 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'e': // STDERR for write only
{
FileAction action;
if (action.Open (STDERR_FILENO, option_arg, false, true))
if (action.Open(STDERR_FILENO, FileSpec{option_arg, false}, false, true))
launch_info.AppendFileAction (action);
break;
}
@ -460,17 +460,18 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'n': // Disable STDIO
{
FileAction action;
if (action.Open (STDIN_FILENO, "/dev/null", true, false))
const FileSpec dev_null{"/dev/null", false};
if (action.Open(STDIN_FILENO, dev_null, true, false))
launch_info.AppendFileAction (action);
if (action.Open (STDOUT_FILENO, "/dev/null", false, true))
if (action.Open(STDOUT_FILENO, dev_null, false, true))
launch_info.AppendFileAction (action);
if (action.Open (STDERR_FILENO, "/dev/null", false, true))
if (action.Open(STDERR_FILENO, dev_null, false, true))
launch_info.AppendFileAction (action);
break;
}
case 'w':
launch_info.SetWorkingDirectory (option_arg);
launch_info.SetWorkingDirectory(FileSpec{option_arg, false});
break;
case 't': // Open process in new terminal window

View File

@ -42,8 +42,11 @@ ProcessLaunchInfo::ProcessLaunchInfo () :
{
}
ProcessLaunchInfo::ProcessLaunchInfo(const char *stdin_path, const char *stdout_path, const char *stderr_path,
const char *working_directory, uint32_t launch_flags) :
ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_directory,
uint32_t launch_flags) :
ProcessInfo(),
m_working_dir(),
m_plugin_name(),
@ -57,28 +60,28 @@ ProcessLaunchInfo::ProcessLaunchInfo(const char *stdin_path, const char *stdout_
m_listener_sp (),
m_hijack_listener_sp()
{
if (stdin_path)
if (stdin_file_spec)
{
FileAction file_action;
const bool read = true;
const bool write = false;
if (file_action.Open(STDIN_FILENO, stdin_path, read, write))
if (file_action.Open(STDIN_FILENO, stdin_file_spec, read, write))
AppendFileAction (file_action);
}
if (stdout_path)
if (stdout_file_spec)
{
FileAction file_action;
const bool read = false;
const bool write = true;
if (file_action.Open(STDOUT_FILENO, stdout_path, read, write))
if (file_action.Open(STDOUT_FILENO, stdout_file_spec, read, write))
AppendFileAction (file_action);
}
if (stderr_path)
if (stderr_file_spec)
{
FileAction file_action;
const bool read = false;
const bool write = true;
if (file_action.Open(STDERR_FILENO, stderr_path, read, write))
if (file_action.Open(STDERR_FILENO, stderr_file_spec, read, write))
AppendFileAction (file_action);
}
if (working_directory)
@ -110,10 +113,11 @@ ProcessLaunchInfo::AppendDuplicateFileAction (int fd, int dup_fd)
}
bool
ProcessLaunchInfo::AppendOpenFileAction (int fd, const char *path, bool read, bool write)
ProcessLaunchInfo::AppendOpenFileAction(int fd, const FileSpec &file_spec,
bool read, bool write)
{
FileAction file_action;
if (file_action.Open (fd, path, read, write))
if (file_action.Open(fd, file_spec, read, write))
{
AppendFileAction (file_action);
return true;
@ -125,7 +129,7 @@ bool
ProcessLaunchInfo::AppendSuppressFileAction (int fd, bool read, bool write)
{
FileAction file_action;
if (file_action.Open (fd, "/dev/null", read, write))
if (file_action.Open(fd, FileSpec{"/dev/null", false}, read, write))
{
AppendFileAction (file_action);
return true;
@ -152,21 +156,16 @@ ProcessLaunchInfo::GetFileActionForFD(int fd) const
return NULL;
}
const char *
ProcessLaunchInfo::GetWorkingDirectory () const
const FileSpec &
ProcessLaunchInfo::GetWorkingDirectory() const
{
if (m_working_dir.empty())
return NULL;
return m_working_dir.c_str();
return m_working_dir;
}
void
ProcessLaunchInfo::SetWorkingDirectory (const char *working_dir)
ProcessLaunchInfo::SetWorkingDirectory(const FileSpec &working_dir)
{
if (working_dir && working_dir[0])
m_working_dir.assign (working_dir);
else
m_working_dir.clear();
m_working_dir = working_dir;
}
const char *
@ -227,7 +226,7 @@ void
ProcessLaunchInfo::Clear ()
{
ProcessInfo::Clear();
m_working_dir.clear();
m_working_dir.Clear();
m_plugin_name.clear();
m_shell.Clear();
m_flags.Clear();
@ -300,57 +299,53 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
// (lldb) settings set target.input-path
// (lldb) settings set target.output-path
// (lldb) settings set target.error-path
FileSpec in_path;
FileSpec out_path;
FileSpec err_path;
FileSpec in_file_spec;
FileSpec out_file_spec;
FileSpec err_file_spec;
if (target)
{
// Only override with the target settings if we don't already have
// an action for in, out or error
if (GetFileActionForFD(STDIN_FILENO) == NULL)
in_path = target->GetStandardInputPath();
in_file_spec = target->GetStandardInputPath();
if (GetFileActionForFD(STDOUT_FILENO) == NULL)
out_path = target->GetStandardOutputPath();
out_file_spec = target->GetStandardOutputPath();
if (GetFileActionForFD(STDERR_FILENO) == NULL)
err_path = target->GetStandardErrorPath();
err_file_spec = target->GetStandardErrorPath();
}
if (log)
log->Printf ("ProcessLaunchInfo::%s target stdin='%s', target stdout='%s', stderr='%s'",
__FUNCTION__,
in_path ? in_path.GetPath().c_str () : "<null>",
out_path ? out_path.GetPath().c_str () : "<null>",
err_path ? err_path.GetPath().c_str () : "<null>");
in_file_spec ? in_file_spec.GetCString() : "<null>",
out_file_spec ? out_file_spec.GetCString() : "<null>",
err_file_spec ? err_file_spec.GetCString() : "<null>");
char path[PATH_MAX];
if (in_path && in_path.GetPath(path, sizeof(path)))
if (in_file_spec)
{
AppendOpenFileAction(STDIN_FILENO, path, true, false);
AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false);
if (log)
log->Printf ("ProcessLaunchInfo::%s appended stdin open file action for %s",
__FUNCTION__,
in_path.GetPath().c_str ());
__FUNCTION__, in_file_spec.GetCString());
}
if (out_path && out_path.GetPath(path, sizeof(path)))
if (out_file_spec)
{
AppendOpenFileAction(STDOUT_FILENO, path, false, true);
AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true);
if (log)
log->Printf ("ProcessLaunchInfo::%s appended stdout open file action for %s",
__FUNCTION__,
out_path.GetPath().c_str ());
__FUNCTION__, out_file_spec.GetCString());
}
if (err_path && err_path.GetPath(path, sizeof(path)))
if (err_file_spec)
{
AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true);
if (log)
log->Printf ("ProcessLaunchInfo::%s appended stderr open file action for %s",
__FUNCTION__,
err_path.GetPath().c_str ());
AppendOpenFileAction(STDERR_FILENO, path, false, true);
__FUNCTION__, err_file_spec.GetCString());
}
if (default_to_use_pty && (!in_path || !out_path || !err_path))
if (default_to_use_pty && (!in_file_spec || !out_file_spec || !err_file_spec))
{
if (log)
log->Printf ("ProcessLaunchInfo::%s default_to_use_pty is set, and at least one stdin/stderr/stdout is unset, so generating a pty to use for it",
@ -365,27 +360,27 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
#endif
if (m_pty->OpenFirstAvailableMaster(open_flags, NULL, 0))
{
const char *slave_path = m_pty->GetSlaveName(NULL, 0);
const FileSpec slave_file_spec{m_pty->GetSlaveName(NULL, 0), false};
// Only use the slave tty if we don't have anything specified for
// input and don't have an action for stdin
if (!in_path && GetFileActionForFD(STDIN_FILENO) == NULL)
if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == NULL)
{
AppendOpenFileAction(STDIN_FILENO, slave_path, true, false);
AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false);
}
// Only use the slave tty if we don't have anything specified for
// output and don't have an action for stdout
if (!out_path && GetFileActionForFD(STDOUT_FILENO) == NULL)
if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == NULL)
{
AppendOpenFileAction(STDOUT_FILENO, slave_path, false, true);
AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true);
}
// Only use the slave tty if we don't have anything specified for
// error and don't have an action for stderr
if (!err_path && GetFileActionForFD(STDERR_FILENO) == NULL)
if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == NULL)
{
AppendOpenFileAction(STDERR_FILENO, slave_path, false, true);
AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true);
}
}
}
@ -432,14 +427,14 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
{
// We have a relative path to our executable which may not work if
// we just try to run "a.out" (without it being converted to "./a.out")
const char *working_dir = GetWorkingDirectory();
FileSpec working_dir = GetWorkingDirectory();
// Be sure to put quotes around PATH's value in case any paths have spaces...
std::string new_path("PATH=\"");
const size_t empty_path_len = new_path.size();
if (working_dir && working_dir[0])
if (working_dir)
{
new_path += working_dir;
new_path += working_dir.GetPath();
}
else
{

View File

@ -2382,9 +2382,8 @@ Target::Install (ProcessLaunchInfo *launch_info)
if (is_main_executable) // TODO: add setting for always installing main executable???
{
// Always install the main executable
remote_file = FileSpec(module_sp->GetFileSpec().GetFilename().AsCString(),
false, module_sp->GetArchitecture());
remote_file.GetDirectory() = platform_sp->GetWorkingDirectory();
remote_file = platform_sp->GetRemoteWorkingDirectory();
remote_file.AppendPathComponent(module_sp->GetFileSpec().GetFilename().GetCString());
}
}
if (remote_file)
@ -2395,7 +2394,7 @@ Target::Install (ProcessLaunchInfo *launch_info)
module_sp->SetPlatformFileSpec(remote_file);
if (is_main_executable)
{
platform_sp->SetFilePermissions(remote_file.GetPath(false).c_str(), 0700);
platform_sp->SetFilePermissions(remote_file, 0700);
if (launch_info)
launch_info->SetExecutableFile(remote_file, false);
}
@ -3620,21 +3619,21 @@ void
TargetProperties::InputPathValueChangedCallback(void *target_property_ptr, OptionValue *)
{
TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
this_->m_launch_info.AppendOpenFileAction(STDIN_FILENO, this_->GetStandardInputPath().GetPath().c_str(), true, false);
this_->m_launch_info.AppendOpenFileAction(STDIN_FILENO, this_->GetStandardInputPath(), true, false);
}
void
TargetProperties::OutputPathValueChangedCallback(void *target_property_ptr, OptionValue *)
{
TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
this_->m_launch_info.AppendOpenFileAction(STDOUT_FILENO, this_->GetStandardOutputPath().GetPath().c_str(), false, true);
this_->m_launch_info.AppendOpenFileAction(STDOUT_FILENO, this_->GetStandardOutputPath(), false, true);
}
void
TargetProperties::ErrorPathValueChangedCallback(void *target_property_ptr, OptionValue *)
{
TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
this_->m_launch_info.AppendOpenFileAction(STDERR_FILENO, this_->GetStandardErrorPath().GetPath().c_str(), false, true);
this_->m_launch_info.AppendOpenFileAction(STDERR_FILENO, this_->GetStandardErrorPath(), false, true);
}
void

View File

@ -49,8 +49,7 @@ MakeDirectory (const FileSpec &dir_path)
return Error ();
}
return FileSystem::MakeDirectory (dir_path.GetPath ().c_str (),
eFilePermissionsDirectoryDefault);
return FileSystem::MakeDirectory(dir_path, eFilePermissionsDirectoryDefault);
}
FileSpec
@ -72,7 +71,7 @@ CreateHostSysRootModuleLink (const FileSpec &root_dir_spec, const char *hostname
if (error.Fail ())
return error;
return FileSystem::Hardlink (sysroot_module_path_spec.GetPath ().c_str (), local_module_spec.GetPath ().c_str ());
return FileSystem::Hardlink(sysroot_module_path_spec, local_module_spec);
}
} // namespace