Index: include/lldb/Host/Host.h =================================================================== --- include/lldb/Host/Host.h +++ include/lldb/Host/Host.h @@ -261,22 +261,22 @@ 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); Index: include/lldb/Target/Platform.h =================================================================== --- include/lldb/Target/Platform.h +++ include/lldb/Target/Platform.h @@ -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 @@ { 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 @@ virtual void AddClangModuleCompilationOptions (Target *target, std::vector &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 @@ } virtual Error - MakeDirectory (const char *path, uint32_t permissions); - + MakeDirectory(const FileSpec &file_spec, uint32_t permissions); + virtual Error - GetFilePermissions (const char *path, uint32_t &file_permissions); + GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions); virtual Error - SetFilePermissions (const char *path, uint32_t file_permissions); + SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions); virtual lldb::user_id_t OpenFile (const FileSpec& file_spec, @@ -711,8 +712,8 @@ 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 @@ 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 @@ } 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 @@ 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; Index: include/lldb/Target/ProcessLaunchInfo.h =================================================================== --- include/lldb/Target/ProcessLaunchInfo.h +++ include/lldb/Target/ProcessLaunchInfo.h @@ -36,11 +36,11 @@ 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_path, + const FileSpec &stdout_path, + const FileSpec &stderr_path, + const FileSpec &working_dir, + uint32_t launch_flags); void AppendFileAction (const FileAction &info) @@ -88,17 +88,11 @@ return m_flags; } - const char * - GetWorkingDirectory () const; - - void - SetWorkingDirectory (const char *working_dir); + const FileSpec & + GetWorkingDirectory() const; void - SwapWorkingDirectory (std::string &working_dir) - { - m_working_dir.swap (working_dir); - } + SetWorkingDirectory(const FileSpec &working_dir); const char * GetProcessPluginName () const; @@ -238,7 +232,7 @@ } 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 Index: source/API/SBLaunchInfo.cpp =================================================================== --- source/API/SBLaunchInfo.cpp +++ source/API/SBLaunchInfo.cpp @@ -175,13 +175,14 @@ const char * SBLaunchInfo::GetWorkingDirectory () const { - return m_opaque_sp->GetWorkingDirectory(); + ConstString working_dir{m_opaque_sp->GetWorkingDirectory().GetPath()}; + return working_dir.GetCString(); } void SBLaunchInfo::SetWorkingDirectory (const char *working_dir) { - m_opaque_sp->SetWorkingDirectory(working_dir); + m_opaque_sp->SetWorkingDirectory(FileSpec{working_dir, false}); } uint32_t Index: source/API/SBPlatform.cpp =================================================================== --- source/API/SBPlatform.cpp +++ source/API/SBPlatform.cpp @@ -318,7 +318,10 @@ { PlatformSP platform_sp(GetSP()); if (platform_sp) - return platform_sp->GetWorkingDirectory().GetCString(); + { + ConstString working_dir{platform_sp->GetWorkingDirectory().GetPath()}; + return working_dir.GetCString(); + } return NULL; } @@ -329,9 +332,9 @@ 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; @@ -537,15 +540,16 @@ if (!command) return Error("invalid shell command (empty)"); - const char *working_dir = shell_command.GetWorkingDirectory(); - if (working_dir == NULL) + const char *wd{shell_command.GetWorkingDirectory()}; + std::string working_dir{wd ? wd : ""}; + if (working_dir.empty()) { - working_dir = platform_sp->GetWorkingDirectory().GetCString(); - if (working_dir) - shell_command.SetWorkingDirectory(working_dir); + working_dir = platform_sp->GetWorkingDirectory().GetPath(); + if (!working_dir.empty()) + shell_command.SetWorkingDirectory(working_dir.c_str()); } return platform_sp->RunShellCommand(command, - working_dir, + FileSpec{working_dir.c_str(), false}, &shell_command.m_opaque_ptr->m_status, &shell_command.m_opaque_ptr->m_signo, &shell_command.m_opaque_ptr->m_output, @@ -598,7 +602,7 @@ 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 +618,7 @@ 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 +632,7 @@ 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 { Index: source/API/SBProcess.cpp =================================================================== --- source/API/SBProcess.cpp +++ source/API/SBProcess.cpp @@ -169,11 +169,11 @@ { 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); Index: source/API/SBTarget.cpp =================================================================== --- source/API/SBTarget.cpp +++ source/API/SBTarget.cpp @@ -345,7 +345,11 @@ 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) Index: source/Commands/CommandObjectPlatform.cpp =================================================================== --- source/Commands/CommandObjectPlatform.cpp +++ source/Commands/CommandObjectPlatform.cpp @@ -558,7 +558,7 @@ 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 { @@ -618,7 +618,7 @@ 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.c_str(), false}, mode); if (error.Success()) { result.SetStatus (eReturnStatusSuccessFinishResult); @@ -2152,7 +2152,7 @@ Error error; if (platform_sp) { - const char *working_dir = NULL; + FileSpec working_dir{}; std::string output; int status = -1; int signo = -1; Index: source/Host/common/Host.cpp =================================================================== --- source/Host/common/Host.cpp +++ source/Host/common/Host.cpp @@ -544,25 +544,25 @@ } 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; @@ -843,16 +843,16 @@ current_dir[0] = '\0'; #endif - const char *working_dir = launch_info.GetWorkingDirectory(); - if (working_dir) + std::string working_dir{launch_info.GetWorkingDirectory().GetPath()}; + if (!working_dir.empty()) { #if defined (__APPLE__) // Set the working directory on this thread only - if (__pthread_chdir (working_dir) < 0) { + if (__pthread_chdir(working_dir.c_str()) < 0) { if (errno == ENOENT) { - error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); + error.SetErrorStringWithFormat("No such file or directory: %s", working_dir.c_str()); } 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.c_str()); } else { error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution."); } @@ -866,10 +866,10 @@ return error; } - if (::chdir(working_dir) == -1) + if (::chdir(working_dir.c_str()) == -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.c_str()); return error; } #endif @@ -933,7 +933,7 @@ } pid = result_pid; - if (working_dir) + if (!working_dir.empty()) { #if defined (__APPLE__) // No more thread specific current working directory Index: source/Host/macosx/Host.mm =================================================================== --- source/Host/macosx/Host.mm +++ source/Host/macosx/Host.mm @@ -411,9 +411,9 @@ 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.GetPath().c_str()); else { char cwd[PATH_MAX]; Index: source/Host/windows/ProcessLauncherWindows.cpp =================================================================== --- source/Host/windows/ProcessLauncherWindows.cpp +++ source/Host/windows/ProcessLauncherWindows.cpp @@ -52,7 +52,7 @@ executable = launch_info.GetExecutableFile().GetPath(); launch_info.GetArguments().GetQuotedCommandString(commandLine); BOOL result = ::CreateProcessA(executable.c_str(), const_cast(commandLine.c_str()), NULL, NULL, TRUE, flags, NULL, - launch_info.GetWorkingDirectory(), &startupinfo, &pi); + launch_info.GetWorkingDirectory().GetPath().c_str(), &startupinfo, &pi); if (result) { // Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess. Index: source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h =================================================================== --- source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h +++ source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h @@ -77,12 +77,12 @@ 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, Index: source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp =================================================================== --- source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -135,12 +135,12 @@ } 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); Index: source/Plugins/Platform/POSIX/PlatformPOSIX.h =================================================================== --- source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -84,17 +84,18 @@ 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 @@ 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; - + MakeDirectory(const lldb_private::FileSpec &file_spec, uint32_t mode) override; + lldb_private::Error - GetFilePermissions (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 char *path, uint32_t file_permissions) override; + 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; Index: source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -85,12 +85,12 @@ } 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 @@ } 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,10 +316,10 @@ } Error -PlatformPOSIX::CreateSymlink(const char *src, const char *dst) +PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) { if (IsHost()) - return FileSystem::Symlink(src, dst); + return FileSystem::Symlink(src.GetPath().c_str(), dst.GetPath().c_str()); else if (m_remote_platform_sp) return m_remote_platform_sp->CreateSymlink(src, dst); else @@ -338,19 +338,19 @@ } Error -PlatformPOSIX::Unlink (const char *path) +PlatformPOSIX::Unlink(const FileSpec &file_spec) { if (IsHost()) - return FileSystem::Unlink(path); + return FileSystem::Unlink(file_spec.GetPath().c_str()); 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 @@ 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 @@ return false; } -lldb_private::ConstString +FileSpec PlatformPOSIX::GetRemoteWorkingDirectory() { if (IsRemote() && m_remote_platform_sp) @@ -545,12 +545,12 @@ } 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 Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h =================================================================== --- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -128,11 +128,11 @@ 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 @@ 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 @@ 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; Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp =================================================================== --- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -320,24 +320,17 @@ 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.GetPath().c_str()); + return working_dir; } else { @@ -346,7 +339,7 @@ } bool -PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const ConstString &path) +PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const FileSpec &working_dir) { if (IsConnected()) { @@ -354,11 +347,12 @@ // 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.GetPath().c_str()); + return m_gdb_client.SetWorkingDir(working_dir) == 0; } else - return Platform::SetRemoteWorkingDirectory(path); + return Platform::SetRemoteWorkingDirectory(working_dir); } bool @@ -398,7 +392,7 @@ 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 { @@ -508,10 +502,10 @@ 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 @@ -751,33 +745,38 @@ } 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.GetPath().c_str(), 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.GetPath().c_str(), 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.GetPath().c_str(), file_permissions, error.GetError(), error.AsCString()); return error; } @@ -833,23 +832,25 @@ } 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.GetPath().c_str(), dst.GetPath().c_str(), 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.GetPath().c_str(), error.GetError(), error.AsCString()); return error; } @@ -860,14 +861,14 @@ } 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 -{ - return m_gdb_client.RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); +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); } void Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1463,15 +1463,12 @@ 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.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.GetPath().c_str()); + return error; } const FileAction *file_action; @@ -1538,7 +1535,7 @@ stdin_path, stdout_path, stderr_path, - working_dir, + ConstString{working_dir.GetPath()}.GetCString(), launch_info, error); Index: source/Plugins/Process/POSIX/ProcessPOSIX.cpp =================================================================== --- source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -52,9 +52,9 @@ { // 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() @@ -170,14 +170,12 @@ 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.GetFileType() != FileSpec::eFileTypeDirectory) + { + error.SetErrorStringWithFormat("No such file or directory: %s", + working_dir.GetPath().c_str()); + return error; } SetPrivateState(eStateLaunching); @@ -200,16 +198,16 @@ file_action = launch_info.GetFileActionForFD (STDERR_FILENO); stderr_path = GetFilePath(file_action, stderr_path, dbg_pts_path); - 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_path, + stdout_path, + stderr_path, + ConstString{working_dir.GetPath()}.GetCString(), + launch_info, + error); m_module = module; Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -243,27 +243,27 @@ /// 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); @@ -463,10 +463,10 @@ 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, @@ -483,26 +483,26 @@ 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); Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1312,7 +1312,7 @@ 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); @@ -2274,7 +2274,7 @@ } bool -GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd) +GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) { StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success) @@ -2283,21 +2283,24 @@ return false; if (response.IsErrorResponse()) return false; - response.GetHexByteString (cwd); + std::string cwd; + response.GetHexByteString(cwd); + working_dir = FileSpec{cwd.c_str(), 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) { @@ -3168,22 +3171,23 @@ } 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(); @@ -3216,14 +3220,15 @@ } 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; @@ -3238,14 +3243,15 @@ } 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; @@ -3288,9 +3294,9 @@ 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()); @@ -3328,9 +3334,9 @@ 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(); @@ -3346,12 +3352,14 @@ } 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; @@ -3470,16 +3478,18 @@ } 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; @@ -3513,14 +3523,15 @@ } 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; @@ -3557,9 +3568,9 @@ 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(); @@ -3581,9 +3592,9 @@ 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(); @@ -3780,7 +3791,7 @@ 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) Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -808,7 +808,7 @@ int status, signo; std::string output; Error err = Host::RunShellCommand(path.c_str(), - working_dir.empty() ? NULL : working_dir.c_str(), + FileSpec{working_dir.c_str(), true}, &status, &signo, &output, timeout); StreamGDBRemote response; if (err.Fail()) Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -954,18 +954,18 @@ packet.SetFilePos (::strlen ("QSetWorkingDir:")); std::string path; packet.GetHexByteString (path); - m_process_launch_info.SwapWorkingDirectory (path); + m_process_launch_info.SetWorkingDirectory(FileSpec{path.c_str(), 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.GetPath().c_str()); return SendPacketNoLock(response.GetData(), response.GetSize()); } Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -882,7 +882,7 @@ const char *stdin_path = NULL; const char *stdout_path = NULL; const char *stderr_path = NULL; - const char *working_dir = launch_info.GetWorkingDirectory(); + FileSpec working_dir = launch_info.GetWorkingDirectory(); const FileAction *file_action; file_action = launch_info.GetFileActionForFD (STDIN_FILENO); @@ -1009,7 +1009,7 @@ 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); } Index: source/Target/Platform.cpp =================================================================== --- source/Target/Platform.cpp +++ source/Target/Platform.cpp @@ -499,7 +499,7 @@ if (GetWorkingDirectory()) { - strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString()); + strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetPath().c_str()); } if (!IsConnected()) return; @@ -610,16 +610,16 @@ } -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 @@ 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.GetPath().c_str()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out } @@ -690,15 +690,13 @@ 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)); 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); + + FileSpec src_resolved = src; + src_resolved.ResolvePath(); + 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 +743,7 @@ if (!fixed_dst.GetFilename()) fixed_dst.GetFilename() = src.GetFilename(); - ConstString working_dir = GetWorkingDirectory(); + FileSpec working_dir = GetWorkingDirectory(); if (dst) { @@ -765,7 +763,7 @@ std::string path; if (working_dir) { - relative_spec.SetFile(working_dir.GetCString(), false); + relative_spec = working_dir; relative_spec.AppendPathComponent(dst.GetPath().c_str()); fixed_dst.GetDirectory() = relative_spec.GetDirectory(); } @@ -780,7 +778,7 @@ { if (working_dir) { - fixed_dst.GetDirectory() = working_dir; + fixed_dst.GetDirectory() = ConstString{working_dir.GetPath()}; } else { @@ -793,7 +791,7 @@ { if (working_dir) { - fixed_dst.GetDirectory() = working_dir; + fixed_dst.GetDirectory() = ConstString{working_dir.GetPath()}; } else { @@ -816,18 +814,17 @@ 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.GetPath().c_str()); 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 +835,18 @@ 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 = src; + src_resolved.ResolvePath(); if (error.Success()) - error = CreateSymlink(dst.GetPath().c_str(), buf); + error = CreateSymlink(dst, src_resolved); } break; case FileSpec::eFileTypePipe: @@ -869,16 +866,17 @@ } 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.GetPath().c_str()); + if (file_spec) { - if (chdir(path.GetCString()) == 0) + if (chdir(file_spec.GetPath().c_str()) == 0) return true; } return false; @@ -886,15 +884,15 @@ 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.GetPath().c_str(), permissions); else { Error error; @@ -904,10 +902,10 @@ } 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.GetPath().c_str(), file_permissions); else { Error error; @@ -917,10 +915,10 @@ } 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.GetPath().c_str(), file_permissions); else { Error error; @@ -947,12 +945,13 @@ } 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.GetPath().c_str()); + m_working_dir = working_dir; return true; } @@ -1470,29 +1469,29 @@ } 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 +1509,12 @@ } 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 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 { if (IsHost()) return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); Index: source/Target/Process.cpp =================================================================== --- source/Target/Process.cpp +++ source/Target/Process.cpp @@ -472,7 +472,7 @@ } case 'w': - launch_info.SetWorkingDirectory (option_arg); + launch_info.SetWorkingDirectory(FileSpec{option_arg, false}); break; case 't': // Open process in new terminal window Index: source/Target/ProcessLaunchInfo.cpp =================================================================== --- source/Target/ProcessLaunchInfo.cpp +++ source/Target/ProcessLaunchInfo.cpp @@ -42,8 +42,11 @@ { } -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 @@ 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.GetPath().c_str(), 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.GetPath().c_str(), 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.GetPath().c_str(), read, write)) AppendFileAction (file_action); } if (working_directory) @@ -152,21 +155,16 @@ 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 +225,7 @@ ProcessLaunchInfo::Clear () { ProcessInfo::Clear(); - m_working_dir.clear(); + m_working_dir.Clear(); m_plugin_name.clear(); m_shell.Clear(); m_flags.Clear(); @@ -432,14 +430,14 @@ { // 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 { Index: source/Target/Target.cpp =================================================================== --- source/Target/Target.cpp +++ source/Target/Target.cpp @@ -2377,9 +2377,8 @@ 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) @@ -2390,7 +2389,7 @@ 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); }