Index: lldb/trunk/include/lldb/Core/ConstString.h =================================================================== --- lldb/trunk/include/lldb/Core/ConstString.h +++ lldb/trunk/include/lldb/Core/ConstString.h @@ -233,7 +233,7 @@ const char * AsCString(const char *value_if_empty = NULL) const { - if (m_string == NULL) + if (IsEmpty()) return value_if_empty; return m_string; } Index: lldb/trunk/include/lldb/Host/File.h =================================================================== --- lldb/trunk/include/lldb/Host/File.h +++ lldb/trunk/include/lldb/Host/File.h @@ -470,7 +470,7 @@ GetPermissions(Error &error) const; static uint32_t - GetPermissions (const char *path, Error &error); + GetPermissions(const FileSpec &file_spec, Error &error); //------------------------------------------------------------------ Index: lldb/trunk/include/lldb/Host/FileSpec.h =================================================================== --- lldb/trunk/include/lldb/Host/FileSpec.h +++ lldb/trunk/include/lldb/Host/FileSpec.h @@ -80,6 +80,10 @@ 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 @@ 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 @@ 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 @@ void AppendPathComponent (const char *new_path); - + + void + AppendPathComponent(const std::string &new_path); + void RemoveLastPathComponent (); Index: lldb/trunk/include/lldb/Host/FileSystem.h =================================================================== --- lldb/trunk/include/lldb/Host/FileSystem.h +++ lldb/trunk/include/lldb/Host/FileSystem.h @@ -24,18 +24,20 @@ 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, Index: lldb/trunk/include/lldb/Host/Host.h =================================================================== --- lldb/trunk/include/lldb/Host/Host.h +++ lldb/trunk/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: lldb/trunk/include/lldb/Target/FileAction.h =================================================================== --- lldb/trunk/include/lldb/Target/FileAction.h +++ lldb/trunk/include/lldb/Target/FileAction.h @@ -11,6 +11,7 @@ #define liblldb_Target_FileAction_h #include +#include "lldb/Host/FileSpec.h" namespace lldb_private { @@ -34,7 +35,7 @@ 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 @@ 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 Index: lldb/trunk/include/lldb/Target/Platform.h =================================================================== --- lldb/trunk/include/lldb/Target/Platform.h +++ lldb/trunk/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: lldb/trunk/include/lldb/Target/ProcessLaunchInfo.h =================================================================== --- lldb/trunk/include/lldb/Target/ProcessLaunchInfo.h +++ lldb/trunk/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_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 @@ 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 @@ 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 +233,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: lldb/trunk/source/API/SBLaunchInfo.cpp =================================================================== --- lldb/trunk/source/API/SBLaunchInfo.cpp +++ lldb/trunk/source/API/SBLaunchInfo.cpp @@ -173,13 +173,13 @@ 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 @@ 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 Index: lldb/trunk/source/API/SBPlatform.cpp =================================================================== --- lldb/trunk/source/API/SBPlatform.cpp +++ lldb/trunk/source/API/SBPlatform.cpp @@ -329,9 +329,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; @@ -545,7 +545,7 @@ 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 @@ 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 @@ 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 @@ 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: lldb/trunk/source/API/SBProcess.cpp =================================================================== --- lldb/trunk/source/API/SBProcess.cpp +++ lldb/trunk/source/API/SBProcess.cpp @@ -167,11 +167,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: lldb/trunk/source/API/SBTarget.cpp =================================================================== --- lldb/trunk/source/API/SBTarget.cpp +++ lldb/trunk/source/API/SBTarget.cpp @@ -343,7 +343,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: lldb/trunk/source/Commands/CommandObjectPlatform.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectPlatform.cpp +++ lldb/trunk/source/Commands/CommandObjectPlatform.cpp @@ -556,7 +556,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 { @@ -616,7 +616,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, false}, mode); if (error.Success()) { result.SetStatus (eReturnStatusSuccessFinishResult); @@ -2150,7 +2150,7 @@ Error error; if (platform_sp) { - const char *working_dir = NULL; + FileSpec working_dir{}; std::string output; int status = -1; int signo = -1; Index: lldb/trunk/source/Host/android/ProcessLauncherAndroid.cpp =================================================================== --- lldb/trunk/source/Host/android/ProcessLauncherAndroid.cpp +++ lldb/trunk/source/Host/android/ProcessLauncherAndroid.cpp @@ -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_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 @@ 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 @@ 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); } Index: lldb/trunk/source/Host/common/Editline.cpp =================================================================== --- lldb/trunk/source/Host/common/Editline.cpp +++ lldb/trunk/source/Host/common/Editline.cpp @@ -193,9 +193,9 @@ { 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()); } Index: lldb/trunk/source/Host/common/File.cpp =================================================================== --- lldb/trunk/source/Host/common/File.cpp +++ lldb/trunk/source/Host/common/File.cpp @@ -325,12 +325,12 @@ } 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 @@ } } else - { - if (path) - error.SetErrorString ("invalid path"); - else - error.SetErrorString ("empty path"); - } + error.SetErrorString ("empty file spec"); return 0; } Index: lldb/trunk/source/Host/common/FileSpec.cpp =================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp +++ lldb/trunk/source/Host/common/FileSpec.cpp @@ -243,7 +243,17 @@ } 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 @@ 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 @@ { 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 @@ 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 &path, bool denormalize) const { @@ -1336,6 +1358,12 @@ } void +FileSpec::AppendPathComponent(const std::string &new_path) +{ + return AppendPathComponent(new_path.c_str()); +} + +void FileSpec::RemoveLastPathComponent () { const bool resolve = false; Index: lldb/trunk/source/Host/common/Host.cpp =================================================================== --- lldb/trunk/source/Host/common/Host.cpp +++ lldb/trunk/source/Host/common/Host.cpp @@ -533,25 +533,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; @@ -597,11 +597,13 @@ 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 @@ 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 @@ } else { - command_output_ptr->resize(file_size); - file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error); + std::vector 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 @@ 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 @@ 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 Index: lldb/trunk/source/Host/common/HostInfoBase.cpp =================================================================== --- lldb/trunk/source/Host/common/HostInfoBase.cpp +++ lldb/trunk/source/Host/common/HostInfoBase.cpp @@ -40,7 +40,7 @@ // 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 @@ 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 @@ 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; Index: lldb/trunk/source/Host/common/Socket.cpp =================================================================== --- lldb/trunk/source/Host/common/Socket.cpp +++ lldb/trunk/source/Host/common/Socket.cpp @@ -504,7 +504,7 @@ 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) { Index: lldb/trunk/source/Host/macosx/Host.mm =================================================================== --- lldb/trunk/source/Host/macosx/Host.mm +++ lldb/trunk/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.GetCString()); else { char cwd[PATH_MAX]; @@ -527,7 +527,7 @@ 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); Index: lldb/trunk/source/Host/posix/FileSystem.cpp =================================================================== --- lldb/trunk/source/Host/posix/FileSystem.cpp +++ lldb/trunk/source/Host/posix/FileSystem.cpp @@ -35,70 +35,61 @@ } 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 @@ } 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 @@ } 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 @@ } 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(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; } Index: lldb/trunk/source/Host/posix/HostProcessPosix.cpp =================================================================== --- lldb/trunk/source/Host/posix/HostProcessPosix.cpp +++ lldb/trunk/source/Host/posix/HostProcessPosix.cpp @@ -69,28 +69,25 @@ // 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//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; } Index: lldb/trunk/source/Host/posix/PipePosix.cpp =================================================================== --- lldb/trunk/source/Host/posix/PipePosix.cpp +++ lldb/trunk/source/Host/posix/PipePosix.cpp @@ -335,7 +335,7 @@ Error PipePosix::Delete(llvm::StringRef name) { - return FileSystem::Unlink(name.data()); + return FileSystem::Unlink(FileSpec{name.data(), true}); } bool Index: lldb/trunk/source/Host/windows/FileSystem.cpp =================================================================== --- lldb/trunk/source/Host/windows/FileSystem.cpp +++ lldb/trunk/source/Host/windows/FileSystem.cpp @@ -23,12 +23,12 @@ } 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 @@ } 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 @@ { // 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 @@ } 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 @@ } 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 @@ } 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 @@ } 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; Index: lldb/trunk/source/Host/windows/ProcessLauncherWindows.cpp =================================================================== --- lldb/trunk/source/Host/windows/ProcessLauncherWindows.cpp +++ lldb/trunk/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().GetCString(), &startupinfo, &pi); if (result) { // Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess. Index: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h =================================================================== --- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h +++ lldb/trunk/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: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -134,12 +134,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: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -324,7 +324,7 @@ 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 Index: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -293,7 +293,7 @@ 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); Index: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h =================================================================== --- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ lldb/trunk/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: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ lldb/trunk/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,7 +316,7 @@ } 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 @@ } 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 @@ 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: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h =================================================================== --- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ lldb/trunk/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: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -318,24 +318,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.GetCString()); + return working_dir; } else { @@ -344,7 +337,7 @@ } bool -PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const ConstString &path) +PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const FileSpec &working_dir) { if (IsConnected()) { @@ -352,11 +345,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.GetCString()); + return m_gdb_client.SetWorkingDir(working_dir) == 0; } else - return Platform::SetRemoteWorkingDirectory(path); + return Platform::SetRemoteWorkingDirectory(working_dir); } bool @@ -396,7 +390,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 { @@ -492,13 +486,13 @@ 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 @@ 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 @@ } 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 @@ } 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 @@ } 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 Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -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 @@ 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 @@ 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 @@ 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); Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -954,17 +954,17 @@ 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 @@ 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 @@ 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 @@ 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 @@ SetState (eStateLaunching); std::unique_ptr 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 @@ 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 @@ } // 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 @@ 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 @@ } 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; Index: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h +++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h @@ -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 @@ 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 @@ 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 @@ 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, Index: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -1185,18 +1185,18 @@ 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 @@ 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(process)), @@ -1242,8 +1242,11 @@ m_operation(0) { std::unique_ptr 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 @@ 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 @@ // // 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 @@ } 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; Index: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h =================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h +++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h @@ -151,8 +151,10 @@ 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. Index: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -50,9 +50,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() @@ -138,27 +138,24 @@ return error; } -const char * -ProcessPOSIX::GetFilePath(const lldb_private::FileAction *file_action, const char *default_path, - const char *dbg_pts_path) -{ - const char *path = NULL; - - if (file_action) - { - 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; - } +FileSpec +ProcessPOSIX::GetFileSpec(const lldb_private::FileAction *file_action, + const FileSpec &default_file_spec, + const FileSpec &dbg_pts_file_spec) +{ + FileSpec file_spec{}; + + if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) + { + 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 @@ 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; Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -205,11 +205,11 @@ /// 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 @@ /// 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 @@ 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 @@ 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: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1325,7 +1325,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); @@ -2221,13 +2221,14 @@ } 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 @@ } 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 @@ } 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 @@ } bool -GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd) +GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) { StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success) @@ -2296,21 +2299,24 @@ 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 @@ } 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 @@ } 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 @@ } 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 @@ 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 @@ 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 @@ } 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 @@ } 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 @@ } 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 @@ 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 @@ 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 @@ 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: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -584,8 +584,8 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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()) Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -950,18 +950,18 @@ 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()); } Index: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -878,45 +878,45 @@ 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 : "", - stdout_path ? stdout_path : "", - stderr_path ? stderr_path : ""); + stdin_file_spec ? stdin_file_spec.GetCString() : "", + stdout_file_spec ? stdout_file_spec.GetCString() : "", + stderr_file_spec ? stderr_file_spec.GetCString() : ""); 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 @@ 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 @@ // 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); - } - if (stdin_path == NULL) - stdin_path = slave_name; + FileSpec slave_name{pty.GetSlaveName(NULL, 0), false}; - if (stdout_path == NULL) - stdout_path = slave_name; + if (!stdin_file_spec) + stdin_file_spec = slave_name; - if (stderr_path == NULL) - stderr_path = slave_name; + if (!stdout_file_spec) + stdout_file_spec = slave_name; + if (!stderr_file_spec) + stderr_file_spec = 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 : "", - stdout_path ? stdout_path : "", - stderr_path ? stderr_path : ""); + stdin_file_spec ? stdin_file_spec.GetCString() : "", + stdout_file_spec ? stdout_file_spec.GetCString() : "", + stderr_file_spec ? stderr_file_spec.GetCString() : ""); } if (log) log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stderr=%s", __FUNCTION__, - stdin_path ? stdin_path : "", - stdout_path ? stdout_path : "", - stderr_path ? stderr_path : ""); - - 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); + stdin_file_spec ? stdin_file_spec.GetCString() : "", + stdout_file_spec ? stdout_file_spec.GetCString() : "", + stderr_file_spec ? stderr_file_spec.GetCString() : ""); + + 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 @@ 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: lldb/trunk/source/Target/FileAction.cpp =================================================================== --- lldb/trunk/source/Target/FileAction.cpp +++ lldb/trunk/source/Target/FileAction.cpp @@ -26,7 +26,7 @@ m_action(eFileActionNone), m_fd(-1), m_arg(-1), - m_path() + m_file_spec() { } @@ -36,21 +36,25 @@ 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 @@ 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 @@ 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; } } Index: lldb/trunk/source/Target/Platform.cpp =================================================================== --- lldb/trunk/source/Target/Platform.cpp +++ lldb/trunk/source/Target/Platform.cpp @@ -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.GetCString()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out } @@ -690,15 +690,15 @@ 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 @@ if (!fixed_dst.GetFilename()) fixed_dst.GetFilename() = src.GetFilename(); - ConstString working_dir = GetWorkingDirectory(); + FileSpec working_dir = GetWorkingDirectory(); if (dst) { @@ -765,8 +765,8 @@ 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 @@ { if (working_dir) { - fixed_dst.GetDirectory() = working_dir; + fixed_dst.GetDirectory().SetCString(working_dir.GetCString()); } else { @@ -793,7 +793,7 @@ { if (working_dir) { - fixed_dst.GetDirectory() = working_dir; + fixed_dst.GetDirectory().SetCString(working_dir.GetCString()); } else { @@ -816,18 +816,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.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 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ } 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 @@ } 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 @@ } 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 @@ } 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); Index: lldb/trunk/source/Target/Process.cpp =================================================================== --- lldb/trunk/source/Target/Process.cpp +++ lldb/trunk/source/Target/Process.cpp @@ -432,7 +432,7 @@ 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 @@ 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 @@ 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 @@ 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 Index: lldb/trunk/source/Target/ProcessLaunchInfo.cpp =================================================================== --- lldb/trunk/source/Target/ProcessLaunchInfo.cpp +++ lldb/trunk/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, 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ // (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 () : "", - out_path ? out_path.GetPath().c_str () : "", - err_path ? err_path.GetPath().c_str () : ""); + in_file_spec ? in_file_spec.GetCString() : "", + out_file_spec ? out_file_spec.GetCString() : "", + err_file_spec ? err_file_spec.GetCString() : ""); - 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 @@ #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 @@ { // 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: lldb/trunk/source/Target/Target.cpp =================================================================== --- lldb/trunk/source/Target/Target.cpp +++ lldb/trunk/source/Target/Target.cpp @@ -2382,9 +2382,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) @@ -2395,7 +2394,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); } @@ -3620,21 +3619,21 @@ TargetProperties::InputPathValueChangedCallback(void *target_property_ptr, OptionValue *) { TargetProperties *this_ = reinterpret_cast(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(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(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 Index: lldb/trunk/source/Utility/ModuleCache.cpp =================================================================== --- lldb/trunk/source/Utility/ModuleCache.cpp +++ lldb/trunk/source/Utility/ModuleCache.cpp @@ -49,8 +49,7 @@ return Error (); } - return FileSystem::MakeDirectory (dir_path.GetPath ().c_str (), - eFilePermissionsDirectoryDefault); + return FileSystem::MakeDirectory(dir_path, eFilePermissionsDirectoryDefault); } FileSpec @@ -72,7 +71,7 @@ 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