diff options
-rw-r--r-- | lldb/include/lldb/Core/Debugger.h | 27 | ||||
-rw-r--r-- | lldb/include/lldb/Core/StreamFile.h | 39 | ||||
-rw-r--r-- | lldb/include/lldb/Host/File.h | 129 | ||||
-rw-r--r-- | lldb/source/API/SBDebugger.cpp | 6 | ||||
-rw-r--r-- | lldb/source/API/SBInstruction.cpp | 2 | ||||
-rw-r--r-- | lldb/source/API/SBStream.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpointCommand.cpp | 57 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectLog.cpp | 11 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectMemory.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 61 | ||||
-rw-r--r-- | lldb/source/Core/InputReader.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Core/Stream.cpp | 1 | ||||
-rw-r--r-- | lldb/source/Core/StreamFile.cpp | 105 | ||||
-rw-r--r-- | lldb/source/Host/common/File.cpp | 299 | ||||
-rw-r--r-- | lldb/source/Host/macosx/Host.mm | 10 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 34 | ||||
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 49 |
17 files changed, 551 insertions, 299 deletions
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index e9b0bf34d45..3384191543b 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -274,6 +274,24 @@ public: void SetAsyncExecution (bool async); + File & + GetInputFile () + { + return m_input_file.GetFile(); + } + + File & + GetOutputFile () + { + return m_output_file.GetFile(); + } + + File & + GetErrorFile () + { + return m_error_file.GetFile(); + } + void SetInputFileHandle (FILE *fh, bool tranfer_ownership); @@ -283,15 +301,6 @@ public: void SetErrorFileHandle (FILE *fh, bool tranfer_ownership); - FILE * - GetInputFileHandle (); - - FILE * - GetOutputFileHandle (); - - FILE * - GetErrorFileHandle (); - Stream& GetOutputStream () { diff --git a/lldb/include/lldb/Core/StreamFile.h b/lldb/include/lldb/Core/StreamFile.h index d0a4a7098f8..0a60a801eac 100644 --- a/lldb/include/lldb/Core/StreamFile.h +++ b/lldb/include/lldb/Core/StreamFile.h @@ -19,6 +19,7 @@ // Project includes #include "lldb/Core/Stream.h" +#include "lldb/Host/File.h" namespace lldb_private { @@ -30,22 +31,28 @@ public: //------------------------------------------------------------------ StreamFile (); - StreamFile (uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order, FILE *f); + StreamFile (uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order); - StreamFile (FILE *f, bool tranfer_ownership = false); + StreamFile (int fd, bool transfer_ownership); - StreamFile (uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order, const char *path, const char *permissions = "w"); + StreamFile (const char *path); - StreamFile (const char *path, const char *permissions = "w"); + StreamFile (FILE *fh, bool transfer_ownership); virtual ~StreamFile(); - void - Close (); + File & + GetFile () + { + return m_file; + } - bool - Open (const char *path, const char *permissions = "w"); + const File & + GetFile () const + { + return m_file; + } virtual void Flush (); @@ -53,25 +60,11 @@ public: virtual int Write (const void *s, size_t length); - FILE * - GetFileHandle (); - - void - SetFileHandle (FILE *file, bool close_file); - - const char * - GetFilePathname (); - - void - SetLineBuffered(); - protected: //------------------------------------------------------------------ // Classes that inherit from StreamFile can see and modify these //------------------------------------------------------------------ - FILE* m_file; ///< File handle to dump to. - bool m_close_file; - std::string m_path_name; + File m_file; private: DISALLOW_COPY_AND_ASSIGN (StreamFile); diff --git a/lldb/include/lldb/Host/File.h b/lldb/include/lldb/Host/File.h index 8ffedc4a7e5..3fd64e4bd7b 100644 --- a/lldb/include/lldb/Host/File.h +++ b/lldb/include/lldb/Host/File.h @@ -25,7 +25,9 @@ namespace lldb_private { class File { public: - + static int kInvalidDescriptor; + static FILE * kInvalidStream; + enum OpenOptions { eOpenOptionRead = (1u << 0), // Open file for reading @@ -34,9 +36,8 @@ public: eOpenOptionNonBlocking = (1u << 3), // File reads eOpenOptionCanCreate = (1u << 4), // Create file if doesn't already exist eOpenOptionCanCreateNewOnly = (1u << 5), // Can create file only if it doesn't already exist - eOpenOptionTruncate = (1u << 6), // Truncate file when opening existing - eOpenOptionSharedLock = (1u << 7), // Open file and get shared lock - eOpenOptionExclusiveLock = (1u << 8) // Open file and get exclusive lock + eOpenOptionSharedLock = (1u << 6), // Open file and get shared lock + eOpenOptionExclusiveLock = (1u << 7) // Open file and get exclusive lock }; enum Permissions @@ -49,13 +50,50 @@ public: ePermissionsGroupExecute = (1u << 5), ePermissionsWorldRead = (1u << 6), ePermissionsWorldWrite = (1u << 7), - ePermissionsWorldExecute = (1u << 8) + ePermissionsWorldExecute = (1u << 8), + + ePermissionsUserRW = (ePermissionsUserRead | ePermissionsUserWrite | 0 ), + ePermissionsUserRX = (ePermissionsUserRead | 0 | ePermissionsUserExecute ), + ePermissionsUserRWX = (ePermissionsUserRead | ePermissionsUserWrite | ePermissionsUserExecute ), + + ePermissionsGroupRW = (ePermissionsGroupRead | ePermissionsGroupWrite | 0 ), + ePermissionsGroupRX = (ePermissionsGroupRead | 0 | ePermissionsGroupExecute ), + ePermissionsGroupRWX = (ePermissionsGroupRead | ePermissionsGroupWrite | ePermissionsGroupExecute ), + + ePermissionsWorldRW = (ePermissionsWorldRead | ePermissionsWorldWrite | 0 ), + ePermissionsWorldRX = (ePermissionsWorldRead | 0 | ePermissionsWorldExecute ), + ePermissionsWorldRWX = (ePermissionsWorldRead | ePermissionsWorldWrite | ePermissionsWorldExecute ), + + ePermissionsEveryoneR = (ePermissionsUserRead | ePermissionsGroupRead | ePermissionsWorldRead ), + ePermissionsEveryoneW = (ePermissionsUserWrite | ePermissionsGroupWrite | ePermissionsWorldWrite ), + ePermissionsEveryoneX = (ePermissionsUserExecute | ePermissionsGroupExecute | ePermissionsWorldExecute ), + + ePermissionsEveryoneRW = (ePermissionsEveryoneR | ePermissionsEveryoneW | 0 ), + ePermissionsEveryoneRX = (ePermissionsEveryoneR | 0 | ePermissionsEveryoneX ), + ePermissionsEveryoneRWX = (ePermissionsEveryoneR | ePermissionsEveryoneW | ePermissionsEveryoneX ), + ePermissionsDefault = (ePermissionsUserRW | ePermissionsGroupRead) }; - File() : m_file_desc (-1) + File() : + m_descriptor (kInvalidDescriptor), + m_stream (kInvalidStream), + m_options (0), + m_owned (false) + { + } + + File (FILE *fh, bool transfer_ownership) : + m_descriptor (kInvalidDescriptor), + m_stream (fh), + m_options (0), + m_owned (transfer_ownership) { } + File (const File &rhs); + + File & + operator= (const File &rhs); //------------------------------------------------------------------ /// Constructor with path. /// @@ -76,8 +114,16 @@ public: //------------------------------------------------------------------ File (const char *path, uint32_t options, - uint32_t permissions); + uint32_t permissions = ePermissionsDefault); + + File (int fd, bool tranfer_ownership) : + m_descriptor (fd), + m_stream (kInvalidStream), + m_options (0), + m_owned (tranfer_ownership) + { + } //------------------------------------------------------------------ /// Destructor. /// @@ -89,7 +135,7 @@ public: bool IsValid () const { - return m_file_desc >= 0; + return DescriptorIsValid() || StreamIsValid(); } //------------------------------------------------------------------ @@ -111,7 +157,7 @@ public: operator bool () const { - return m_file_desc >= 0; + return DescriptorIsValid() || StreamIsValid(); } //------------------------------------------------------------------ @@ -133,7 +179,7 @@ public: bool operator! () const { - return m_file_desc < 0; + return !DescriptorIsValid() && !StreamIsValid(); } //------------------------------------------------------------------ @@ -163,11 +209,26 @@ public: Error Open (const char *path, uint32_t options, - uint32_t permissions); + uint32_t permissions = ePermissionsDefault); Error Close (); + Error + Duplicate (const File &rhs); + + int + GetDescriptor() const; + + void + SetDescriptor(int fd, bool transfer_ownership); + + FILE * + GetStream (); + + void + SetStream (FILE *fh, bool transfer_ownership); + //------------------------------------------------------------------ /// Read bytes from a file from the current file position. /// @@ -328,6 +389,15 @@ public: Error Write (const void *src, size_t &num_bytes, off_t &offset); + //------------------------------------------------------------------ + /// Flush the current stream + /// + /// @return + /// An error object that indicates success or the reason for + /// failure. + //------------------------------------------------------------------ + Error + Flush (); //------------------------------------------------------------------ /// Sync to disk. @@ -339,11 +409,46 @@ public: Error Sync (); + //------------------------------------------------------------------ + /// Output printf formatted output to the stream. + /// + /// Print some formatted output to the stream. + /// + /// @param[in] format + /// A printf style format string. + /// + /// @param[in] ... + /// Variable arguments that are needed for the printf style + /// format string \a format. + //------------------------------------------------------------------ + int + Printf (const char *format, ...); + + int + PrintfVarArg(const char *format, va_list args); + protected: + + + bool + DescriptorIsValid () const + { + return m_descriptor >= 0; + } + + bool + StreamIsValid () const + { + return m_stream != kInvalidStream; + } + //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ - int m_file_desc; ///< The open file handle or NULL if the file isn't opened + int m_descriptor; + FILE *m_stream; + uint32_t m_options; + bool m_owned; }; } // namespace lldb_private diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 6901fa2632b..430700d1896 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -193,7 +193,7 @@ FILE * SBDebugger::GetInputFileHandle () { if (m_opaque_sp) - return m_opaque_sp->GetInputFileHandle(); + return m_opaque_sp->GetInputFile().GetStream(); return NULL; } @@ -201,7 +201,7 @@ FILE * SBDebugger::GetOutputFileHandle () { if (m_opaque_sp) - return m_opaque_sp->GetOutputFileHandle(); + return m_opaque_sp->GetOutputFile().GetStream(); return NULL; } @@ -209,7 +209,7 @@ FILE * SBDebugger::GetErrorFileHandle () { if (m_opaque_sp) - return m_opaque_sp->GetErrorFileHandle(); + return m_opaque_sp->GetErrorFile().GetStream(); return NULL; } diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp index 01718a3d844..df3a7535cbb 100644 --- a/lldb/source/API/SBInstruction.cpp +++ b/lldb/source/API/SBInstruction.cpp @@ -103,7 +103,7 @@ SBInstruction::Print (FILE *out) if (m_opaque_sp) { - StreamFile out_stream (out); + StreamFile out_stream (out, false); m_opaque_sp->Dump (&out_stream, true, NULL, 0, NULL, false); } } diff --git a/lldb/source/API/SBStream.cpp b/lldb/source/API/SBStream.cpp index b8a18a14033..661c0f0a3c3 100644 --- a/lldb/source/API/SBStream.cpp +++ b/lldb/source/API/SBStream.cpp @@ -9,6 +9,7 @@ #include "lldb/API/SBStream.h" +#include "lldb/Core/Error.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" @@ -75,7 +76,13 @@ SBStream::RedirectToFile (const char *path, bool append) if (!m_is_file) local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString()); } - m_opaque_ap.reset (new StreamFile (path, append ? "a" : "w")); + StreamFile *stream_file = new StreamFile; + uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; + if (append) + open_options |= File::eOpenOptionAppend; + stream_file->GetFile().Open (path, open_options, File::ePermissionsDefault); + + m_opaque_ap.reset (stream_file); if (m_opaque_ap.get()) { diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index c706bb555a6..0024e6d2e80 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -418,28 +418,25 @@ CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback size_t bytes_len ) { - FILE *out_fh = reader.GetDebugger().GetOutputFileHandle(); + File &out_file = reader.GetDebugger().GetOutputFile(); switch (notification) { case eInputReaderActivate: - if (out_fh) - { - ::fprintf (out_fh, "%s\n", g_reader_instructions); - if (reader.GetPrompt()) - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); - } + out_file.Printf ("%s\n", g_reader_instructions); + if (reader.GetPrompt()) + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush(); break; case eInputReaderDeactivate: break; case eInputReaderReactivate: - if (out_fh && reader.GetPrompt()) + if (reader.GetPrompt()) { - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush(); } break; @@ -454,10 +451,10 @@ CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback ((BreakpointOptions::CommandData *)bp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len); } } - if (out_fh && !reader.IsDone() && reader.GetPrompt()) + if (!reader.IsDone() && reader.GetPrompt()) { - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush(); } break; @@ -475,8 +472,8 @@ CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->script_source.Clear(); } } - ::fprintf (out_fh, "Warning: No command attached to breakpoint.\n"); - ::fflush (out_fh); + out_file.Printf ("Warning: No command attached to breakpoint.\n"); + out_file.Flush(); } break; @@ -774,8 +771,8 @@ CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction Debugger &debugger = context->exe_ctx.target->GetDebugger(); CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); - FILE *out_fh = debugger.GetOutputFileHandle(); - FILE *err_fh = debugger.GetErrorFileHandle(); + File &out_file = debugger.GetOutputFile(); + File &err_file = debugger.GetErrorFile(); uint32_t i; for (i = 0; i < num_commands; ++i) @@ -797,30 +794,24 @@ CommandObjectBreakpointCommand::BreakpointOptionsCallbackFunction { if (i < num_commands - 1) { - if (out_fh) - ::fprintf (out_fh, "Short-circuiting command execution because target state changed to %s." - " last command: \"%s\"\n", StateAsCString(internal_state), - commands.GetStringAtIndex(i)); + out_file.Printf ("Short-circuiting command execution because target state changed to %s." + " last command: \"%s\"\n", StateAsCString(internal_state), + commands.GetStringAtIndex(i)); } break; } - if (out_fh) - ::fprintf (out_fh, "%s", result.GetErrorStream().GetData()); - if (err_fh) - ::fprintf (err_fh, "%s", result.GetOutputStream().GetData()); + out_file.Printf ("%s", result.GetErrorStream().GetData()); + err_file.Printf ("%s", result.GetOutputStream().GetData()); result.Clear(); result.SetStatus (eReturnStatusSuccessFinishNoResult); } - if (err_fh && !result.Succeeded() && i < num_commands) - ::fprintf (err_fh, "Attempt to execute '%s' failed.\n", commands.GetStringAtIndex(i)); - - if (out_fh) - ::fprintf (out_fh, "%s", result.GetErrorStream().GetData()); + if (!result.Succeeded() && i < num_commands) + err_file.Printf ("Attempt to execute '%s' failed.\n", commands.GetStringAtIndex(i)); - if (err_fh) - ::fprintf (err_fh, "%s", result.GetOutputStream().GetData()); + out_file.Printf ("%s", result.GetErrorStream().GetData()); + err_file.Printf ("%s", result.GetOutputStream().GetData()); } } return ret_value; diff --git a/lldb/source/Commands/CommandObjectLog.cpp b/lldb/source/Commands/CommandObjectLog.cpp index cf090af05e6..b887f1cc9f4 100644 --- a/lldb/source/Commands/CommandObjectLog.cpp +++ b/lldb/source/Commands/CommandObjectLog.cpp @@ -113,19 +113,16 @@ public: std::string channel(args.GetArgumentAtIndex(0)); args.Shift (); // Shift off the channel StreamSP log_stream_sp; - StreamFile *log_file_ptr = NULL; // This will get put in the log_stream_sp, no need to free it. if (m_options.log_file.empty()) { - log_file_ptr = new StreamFile(m_interpreter.GetDebugger().GetOutputFileHandle()); - log_stream_sp.reset(log_file_ptr); + log_stream_sp.reset(new StreamFile(m_interpreter.GetDebugger().GetOutputFile().GetDescriptor(), false)); } else { LogStreamMap::iterator pos = m_log_streams.find(m_options.log_file); if (pos == m_log_streams.end()) { - log_file_ptr = new StreamFile (m_options.log_file.c_str(), "w"); - log_stream_sp.reset (log_file_ptr); + log_stream_sp.reset (new StreamFile (m_options.log_file.c_str())); m_log_streams[m_options.log_file] = log_stream_sp; } else @@ -133,10 +130,6 @@ public: } assert (log_stream_sp.get()); - // If we ended up making a StreamFile for log output, line buffer it. - if (log_file_ptr != NULL) - log_file_ptr->SetLineBuffered(); - uint32_t log_options = m_options.log_options; if (log_options == 0) log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index 3020c01de81..949cadca352 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -347,7 +347,7 @@ public: if (m_options.m_append_to_outfile) mode[0] = 'a'; - if (outfile_stream.Open (path, mode)) + if (outfile_stream.GetFile ().Open (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate).Success()) { if (m_options.m_output_as_binary) { diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 33a9b91e906..10bb26791a1 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -245,64 +245,44 @@ Debugger::DisconnectInput() void Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) { - m_input_file.SetFileHandle (fh, tranfer_ownership); - if (m_input_file.GetFileHandle() == NULL) - m_input_file.SetFileHandle (stdin, false); + File &in_file = GetInputFile(); + in_file.SetStream (fh, tranfer_ownership); + if (in_file.IsValid() == false) + in_file.SetStream (stdin, true); // Disconnect from any old connection if we had one m_input_comm.Disconnect (); - m_input_comm.SetConnection (new ConnectionFileDescriptor (::fileno (GetInputFileHandle()), true)); + m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), true)); m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); Error error; if (m_input_comm.StartReadThread (&error) == false) { - FILE *err_fh = GetErrorFileHandle(); - if (err_fh) - { - ::fprintf (err_fh, "error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); - exit(1); - } - } - -} + File &err_file = GetErrorFile(); -FILE * -Debugger::GetInputFileHandle () -{ - return m_input_file.GetFileHandle(); + err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); + exit(1); + } } - void Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) { - m_output_file.SetFileHandle (fh, tranfer_ownership); - if (m_output_file.GetFileHandle() == NULL) - m_output_file.SetFileHandle (stdin, false); + File &out_file = GetOutputFile(); + out_file.SetStream (fh, tranfer_ownership); + if (out_file.IsValid() == false) + out_file.SetStream (stdout, false); GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh); } -FILE * -Debugger::GetOutputFileHandle () -{ - return m_output_file.GetFileHandle(); -} - void Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) { - m_error_file.SetFileHandle (fh, tranfer_ownership); - if (m_error_file.GetFileHandle() == NULL) - m_error_file.SetFileHandle (stdin, false); -} - - -FILE * -Debugger::GetErrorFileHandle () -{ - return m_error_file.GetFileHandle(); + File &err_file = GetErrorFile(); + err_file.SetStream (fh, tranfer_ownership); + if (err_file.IsValid() == false) + err_file.SetStream (stderr, false); } CommandInterpreter & @@ -547,12 +527,11 @@ Debugger::CheckIfTopInputReaderIsDone () void Debugger::ActivateInputReader (const InputReaderSP &reader_sp) { - FILE *in_fh = GetInputFileHandle(); + int input_fd = m_input_file.GetFile().GetDescriptor(); - if (in_fh) + if (input_fd >= 0) { - int in_fd = fileno (in_fh); - Terminal tty(in_fd); + Terminal tty(input_fd); tty.SetEcho(reader_sp->GetEcho()); diff --git a/lldb/source/Core/InputReader.cpp b/lldb/source/Core/InputReader.cpp index b8a61c29953..fc94bed0834 100644 --- a/lldb/source/Core/InputReader.cpp +++ b/lldb/source/Core/InputReader.cpp @@ -302,9 +302,12 @@ InputReader::RefreshPrompt () { if (!m_prompt.empty()) { - FILE *out_fh = m_debugger.GetOutputFileHandle(); - if (out_fh) - ::fprintf (out_fh, "%s", m_prompt.c_str()); + File &out_file = m_debugger.GetOutputFile(); + if (out_file.IsValid()) + { + out_file.Printf ("%s", m_prompt.c_str()); + out_file.Flush(); + } } } diff --git a/lldb/source/Core/Stream.cpp b/lldb/source/Core/Stream.cpp index c4a23a7a27b..77fc0d53dea 100644 --- a/lldb/source/Core/Stream.cpp +++ b/lldb/source/Core/Stream.cpp @@ -211,7 +211,6 @@ Stream::PrintfVarArg (const char *format, va_list args) size_t length = ::vsnprintf (str, sizeof(str), format, args); if (length < sizeof(str)) { - va_end (args); // Include the NULL termination byte for binary output if (m_flags.Test(eBinary)) length += 1; diff --git a/lldb/source/Core/StreamFile.cpp b/lldb/source/Core/StreamFile.cpp index 5fb42d94703..0d5750801aa 100644 --- a/lldb/source/Core/StreamFile.cpp +++ b/lldb/source/Core/StreamFile.cpp @@ -8,13 +8,14 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/StreamFile.h" -#include "lldb/Host/Config.h" -#include <stdio.h> // C Includes +#include <stdio.h> // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/Error.h" + using namespace lldb; using namespace lldb_private; @@ -24,122 +25,48 @@ using namespace lldb_private; //---------------------------------------------------------------------- StreamFile::StreamFile () : Stream (), - m_file (NULL), - m_close_file (false), - m_path_name () + m_file () { } -StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order, FILE *f) : +StreamFile::StreamFile (uint32_t flags, uint32_t addr_size, ByteOrder byte_order) : Stream (flags, addr_size, byte_order), - m_file (f), - m_close_file (false), - m_path_name () + m_file () { } -StreamFile::StreamFile(FILE *f, bool tranfer_ownership) : +StreamFile::StreamFile (int fd, bool transfer_ownership) : Stream (), - m_file (f), - m_close_file (tranfer_ownership), - m_path_name () + m_file (fd, transfer_ownership) { } -StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order, const char *path, const char *permissions) : - Stream (flags, addr_size, byte_order), - m_file (NULL), - m_close_file(false), - m_path_name (path) +StreamFile::StreamFile (FILE *fh, bool transfer_ownership) : + Stream (), + m_file (fh, transfer_ownership) { - Open(path, permissions); } -StreamFile::StreamFile(const char *path, const char *permissions) : +StreamFile::StreamFile (const char *path) : Stream (), - m_file (NULL), - m_close_file(false), - m_path_name (path) + m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate, File::ePermissionsDefault) { - Open(path, permissions); } StreamFile::~StreamFile() { - Close (); -} - -void -StreamFile::Close () -{ - if (m_close_file && m_file != NULL) - ::fclose (m_file); - m_file = NULL; - m_close_file = false; -} - -bool -StreamFile::Open (const char *path, const char *permissions) -{ - Close(); - if (path && path[0]) - { - if ((m_path_name.size() == 0) - || (m_path_name.compare(path) != 0)) - m_path_name = path; - m_file = ::fopen (path, permissions); - if (m_file != NULL) - m_close_file = true; - } - return m_file != NULL; -} - -void -StreamFile::SetLineBuffered () -{ - // TODO: check if we can get rid of this LLDB_CONFIG if we do a: - // setvbuf(m_file, (char *)NULL, _IOLBF, 0); -#ifdef LLDB_CONFIG_SUPPORTS_SETLINEBUFFERED - if (m_file != NULL) - setlinebuf (m_file); -#endif // #ifdef LLDB_CONFIG_SUPPORTS_SETLINEBUFFERED } void StreamFile::Flush () { - if (m_file) - ::fflush (m_file); + m_file.Flush(); } int StreamFile::Write (const void *s, size_t length) { - if (m_file) - return ::fwrite (s, 1, length, m_file); - return 0; -} - -FILE * -StreamFile::GetFileHandle() -{ - return m_file; -} - -void -StreamFile::SetFileHandle (FILE *file, bool close_file) -{ - Close(); - m_file = file; - m_close_file = close_file; -} - -const char * -StreamFile::GetFilePathname () -{ - if (m_path_name.size() == 0) - return NULL; - else - return m_path_name.c_str(); + m_file.Write (s, length); + return length; } diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp index 6bfb5d6d901..e2dd32cca00 100644 --- a/lldb/source/Host/common/File.cpp +++ b/lldb/source/Host/common/File.cpp @@ -18,17 +18,160 @@ using namespace lldb; using namespace lldb_private; +static const char * +GetStreamOpenModeFromOptions (uint32_t options) +{ + if (options & File::eOpenOptionAppend) + { + if (options & File::eOpenOptionRead) + { + if (options & File::eOpenOptionCanCreateNewOnly) + return "a+x"; + else + return "a+"; + } + else if (options & File::eOpenOptionWrite) + { + if (options & File::eOpenOptionCanCreateNewOnly) + return "ax"; + else + return "a"; + } + } + else if (options & File::eOpenOptionRead && options & File::eOpenOptionWrite) + { + if (options & File::eOpenOptionCanCreate) + { + if (options & File::eOpenOptionCanCreateNewOnly) + return "w+x"; + else + return "w+"; + } + else + return "r+"; + } + else if (options & File::eOpenOptionRead) + { + return "r"; + } + else if (options & File::eOpenOptionWrite) + { + return "w"; + } + return NULL; +} + +int File::kInvalidDescriptor = -1; +FILE * File::kInvalidStream = NULL; + File::File(const char *path, uint32_t options, uint32_t permissions) : - m_file_desc (-1) + m_descriptor (kInvalidDescriptor), + m_stream (kInvalidStream), + m_options (0), + m_owned (false) { Open (path, options, permissions); } +File::File (const File &rhs) : + m_descriptor (kInvalidDescriptor), + m_stream (kInvalidStream), + m_options (0), + m_owned (false) +{ + Duplicate (rhs); +} + + +File & +File::operator = (const File &rhs) +{ + if (this != &rhs) + Duplicate (rhs); + return *this; +} + File::~File() { Close (); } + +int +File::GetDescriptor() const +{ + if (DescriptorIsValid()) + return m_descriptor; + + // Don't open the file descriptor if we don't need to, just get it from the + // stream if we have one. + if (StreamIsValid()) + return fileno (m_stream); + + // Invalid descriptor and invalid stream, return invalid descriptor. + return kInvalidDescriptor; +} + +void +File::SetDescriptor (int fd, bool transfer_ownership) +{ + if (IsValid()) + Close(); + m_descriptor = fd; + m_owned = transfer_ownership; +} + + +FILE * +File::GetStream () +{ + if (!StreamIsValid()) + { + if (DescriptorIsValid()) + { + const char *mode = GetStreamOpenModeFromOptions (m_options); + if (mode) + m_stream = ::fdopen (m_descriptor, mode); + } + } + return m_stream; +} + + +void +File::SetStream (FILE *fh, bool transfer_ownership) +{ + if (IsValid()) + Close(); + m_stream = fh; + m_owned = transfer_ownership; +} + +Error +File::Duplicate (const File &rhs) +{ + Error error; + if (IsValid ()) + Close(); + + if (rhs.DescriptorIsValid()) + { + m_descriptor = ::fcntl(rhs.GetDescriptor(), F_DUPFD); + if (!DescriptorIsValid()) + error.SetErrorToErrno(); + else + { + m_options = rhs.m_options; + m_owned = true; + } + } + else + { + error.SetErrorString ("invalid file to duplicate"); + } + return error; +} + Error File::Open (const char *path, uint32_t options, uint32_t permissions) { @@ -50,6 +193,8 @@ File::Open (const char *path, uint32_t options, uint32_t permissions) if (options & eOpenOptionAppend) oflag |= O_APPEND; + else + oflag |= O_TRUNC; if (options & eOpenOptionCanCreate) oflag |= O_CREAT; @@ -57,8 +202,6 @@ File::Open (const char *path, uint32_t options, uint32_t permissions) if (options & eOpenOptionCanCreateNewOnly) oflag |= O_CREAT | O_EXCL; - if (options & eOpenOptionTruncate) - oflag |= O_TRUNC; if (options & eOpenOptionSharedLock) oflag |= O_SHLOCK; @@ -77,9 +220,11 @@ File::Open (const char *path, uint32_t options, uint32_t permissions) if (permissions & ePermissionsWorldWrite) mode |= S_IWOTH; if (permissions & ePermissionsWorldExecute) mode |= S_IXOTH; - m_file_desc = ::open(path, oflag, mode); - if (m_file_desc == -1) + m_descriptor = ::open(path, oflag, mode); + if (!DescriptorIsValid()) error.SetErrorToErrno(); + else + m_owned = true; return error; } @@ -90,9 +235,24 @@ File::Close () Error error; if (IsValid ()) { - if (::close (m_file_desc) != 0) - error.SetErrorToErrno(); - m_file_desc = -1; + if (m_owned) + { + if (StreamIsValid()) + { + if (::fclose (m_stream) == EOF) + error.SetErrorToErrno(); + } + + if (DescriptorIsValid()) + { + if (::close (m_descriptor) != 0) + error.SetErrorToErrno(); + } + } + m_descriptor = kInvalidDescriptor; + m_stream = kInvalidStream; + m_options = 0; + m_owned = false; } return error; } @@ -105,7 +265,7 @@ File::GetFileSpec (FileSpec &file_spec) const if (IsValid ()) { char path[PATH_MAX]; - if (::fcntl(m_file_desc, F_GETPATH, path) == -1) + if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1) error.SetErrorToErrno(); else file_spec.SetFile (path, false); @@ -122,9 +282,9 @@ Error File::SeekFromStart (off_t& offset) { Error error; - if (IsValid ()) + if (DescriptorIsValid()) { - offset = ::lseek (m_file_desc, offset, SEEK_SET); + offset = ::lseek (m_descriptor, offset, SEEK_SET); if (offset == -1) error.SetErrorToErrno(); @@ -140,9 +300,9 @@ Error File::SeekFromCurrent (off_t& offset) { Error error; - if (IsValid ()) + if (DescriptorIsValid()) { - offset = ::lseek (m_file_desc, offset, SEEK_CUR); + offset = ::lseek (m_descriptor, offset, SEEK_CUR); if (offset == -1) error.SetErrorToErrno(); @@ -158,9 +318,9 @@ Error File::SeekFromEnd (off_t& offset) { Error error; - if (IsValid ()) + if (DescriptorIsValid()) { - offset = ::lseek (m_file_desc, offset, SEEK_CUR); + offset = ::lseek (m_descriptor, offset, SEEK_CUR); if (offset == -1) error.SetErrorToErrno(); @@ -173,12 +333,29 @@ File::SeekFromEnd (off_t& offset) } Error +File::Flush () +{ + Error error; + if (StreamIsValid()) + { + if (::fflush (m_stream) == EOF) + error.SetErrorToErrno(); + } + else if (!DescriptorIsValid()) + { + error.SetErrorString("invalid file handle"); + } + return error; +} + + +Error File::Sync () { Error error; - if (IsValid ()) + if (DescriptorIsValid()) { - if (::fsync (m_file_desc) == -1) + if (::fsync (m_descriptor) == -1) error.SetErrorToErrno(); } else @@ -192,9 +369,9 @@ Error File::Read (void *buf, size_t &num_bytes) { Error error; - if (IsValid ()) + if (DescriptorIsValid()) { - ssize_t bytes_read = ::read (m_file_desc, buf, num_bytes); + ssize_t bytes_read = ::read (m_descriptor, buf, num_bytes); if (bytes_read == -1) { error.SetErrorToErrno(); @@ -203,6 +380,20 @@ File::Read (void *buf, size_t &num_bytes) else num_bytes = bytes_read; } + else if (StreamIsValid()) + { + size_t bytes_read = ::fread (buf, 1, num_bytes, m_stream); + if (bytes_read == 0) + { + if (::feof(m_stream)) + error.SetErrorString ("feof"); + else if (::ferror (m_stream)) + error.SetErrorString ("ferror"); + num_bytes = 0; + } + else + num_bytes = bytes_read; + } else { num_bytes = 0; @@ -215,9 +406,9 @@ Error File::Write (const void *buf, size_t &num_bytes) { Error error; - if (IsValid()) + if (DescriptorIsValid()) { - ssize_t bytes_written = ::write (m_file_desc, buf, num_bytes); + ssize_t bytes_written = ::write (m_descriptor, buf, num_bytes); if (bytes_written == -1) { error.SetErrorToErrno(); @@ -226,6 +417,21 @@ File::Write (const void *buf, size_t &num_bytes) else num_bytes = bytes_written; } + else if (StreamIsValid()) + { + size_t bytes_written = ::fwrite (buf, 1, num_bytes, m_stream); + if (bytes_written == 0) + { + if (::feof(m_stream)) + error.SetErrorString ("feof"); + else if (::ferror (m_stream)) + error.SetErrorString ("ferror"); + num_bytes = 0; + } + else + num_bytes = bytes_written; + + } else { num_bytes = 0; @@ -239,9 +445,10 @@ Error File::Read (void *buf, size_t &num_bytes, off_t &offset) { Error error; - if (IsValid ()) + int fd = GetDescriptor(); + if (fd != kInvalidDescriptor) { - ssize_t bytes_read = ::pread (m_file_desc, buf, num_bytes, offset); + ssize_t bytes_read = ::pread (fd, buf, num_bytes, offset); if (bytes_read < 0) { num_bytes = 0; @@ -265,9 +472,10 @@ Error File::Write (const void *buf, size_t &num_bytes, off_t &offset) { Error error; - if (IsValid()) + int fd = GetDescriptor(); + if (fd != kInvalidDescriptor) { - ssize_t bytes_written = ::pwrite (m_file_desc, buf, num_bytes, offset); + ssize_t bytes_written = ::pwrite (m_descriptor, buf, num_bytes, offset); if (bytes_written < 0) { num_bytes = 0; @@ -287,5 +495,44 @@ File::Write (const void *buf, size_t &num_bytes, off_t &offset) return error; } +//------------------------------------------------------------------ +// Print some formatted output to the stream. +//------------------------------------------------------------------ +int +File::Printf (const char *format, ...) +{ + va_list args; + va_start (args, format); + int result = PrintfVarArg (format, args); + va_end (args); + return result; +} - +//------------------------------------------------------------------ +// Print some formatted output to the stream. +//------------------------------------------------------------------ +int +File::PrintfVarArg (const char *format, va_list args) +{ + int result = 0; + if (DescriptorIsValid()) + { + char *s = NULL; + result = vasprintf(&s, format, args); + if (s != NULL) + { + if (result > 0) + { + size_t s_len = result; + Write (s, s_len); + result = s_len; + } + free (s); + } + } + else if (StreamIsValid()) + { + result = ::vfprintf (m_stream, format, args); + } + return result; +} diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index 5b14f18b673..552c7b34098 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -255,7 +255,13 @@ LaunchInNewTerminalWithCommandFile ::strncat (temp_file_path, ".command", sizeof (temp_file_path)); - StreamFile command_file (temp_file_path, "w"); + StreamFile command_file; + command_file.GetFile().Open (temp_file_path, + File::eOpenOptionWrite | File::eOpenOptionCanCreate, + File::ePermissionsDefault); + + if (!command_file.GetFile().IsValid()) + return LLDB_INVALID_PROCESS_ID; FileSpec darwin_debug_file_spec; if (!Host::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec)) @@ -291,7 +297,7 @@ LaunchInNewTerminalWithCommandFile } } command_file.PutCString("\necho Process exited with status $?\n"); - command_file.Close(); + command_file.GetFile().Close(); if (::chmod (temp_file_path, S_IRWXU | S_IRWXG) != 0) return LLDB_INVALID_PROCESS_ID; diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index e239c5596a0..8a302feccab 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -1102,24 +1102,27 @@ CommandInterpreter::SetPrompt (const char *new_prompt) } size_t -CommandInterpreter::GetConfirmationInputReaderCallback (void *baton, - InputReader &reader, - lldb::InputReaderAction action, - const char *bytes, - size_t bytes_len) +CommandInterpreter::GetConfirmationInputReaderCallback +( + void *baton, + InputReader &reader, + lldb::InputReaderAction action, + const char *bytes, + size_t bytes_len +) { - FILE *out_fh = reader.GetDebugger().GetOutputFileHandle(); + File &out_file = reader.GetDebugger().GetOutputFile(); bool *response_ptr = (bool *) baton; switch (action) { case eInputReaderActivate: - if (out_fh) + if (out_file.IsValid()) { if (reader.GetPrompt()) { - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush (); } } break; @@ -1128,10 +1131,10 @@ CommandInterpreter::GetConfirmationInputReaderCallback (void *baton, break; case eInputReaderReactivate: - if (out_fh && reader.GetPrompt()) + if (out_file.IsValid() && reader.GetPrompt()) { - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush (); } break; @@ -1152,11 +1155,10 @@ CommandInterpreter::GetConfirmationInputReaderCallback (void *baton, } else { - if (out_fh && !reader.IsDone() && reader.GetPrompt()) + if (out_file.IsValid() && !reader.IsDone() && reader.GetPrompt()) { - ::fprintf (out_fh, "Please answer \"y\" or \"n\"\n"); - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("Please answer \"y\" or \"n\"\n%s", reader.GetPrompt()); + out_file.Flush (); } } break; diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index 88f42233789..54d46068905 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -198,7 +198,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete ScriptInterpreter (interpreter, eScriptLanguagePython), m_embedded_python_pty (), m_embedded_thread_input_reader_sp (), - m_dbg_stdout (interpreter.GetDebugger().GetOutputFileHandle()), + m_dbg_stdout (interpreter.GetDebugger().GetOutputFile().GetStream()), m_new_sysout (NULL), m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()), m_terminal_state (), @@ -570,24 +570,17 @@ ScriptInterpreterPython::InputReaderCallback if (script_interpreter->m_script_lang != eScriptLanguagePython) return 0; - FILE *out_fh = reader.GetDebugger().GetOutputFileHandle (); - if (out_fh == NULL) - out_fh = stdout; + File &out_file = reader.GetDebugger().GetOutputFile(); switch (notification) { case eInputReaderActivate: { - if (out_fh) - { - ::fprintf (out_fh, "Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.\n"); - } + out_file.Printf ("Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.\n"); + // Save terminal settings if we can - int input_fd; - FILE *input_fh = reader.GetDebugger().GetInputFileHandle(); - if (input_fh != NULL) - input_fd = ::fileno (input_fh); - else + int input_fd = reader.GetDebugger().GetInputFile().GetDescriptor(); + if (input_fd == File::kInvalidDescriptor) input_fd = STDIN_FILENO; script_interpreter->SaveTerminalState(input_fd); @@ -596,7 +589,7 @@ ScriptInterpreterPython::InputReaderCallback { while (!GetPythonLock(1)) { - ::fprintf (out_fh, "Python interpreter locked on another thread; waiting to acquire lock...\n"); + out_file.Printf ("Python interpreter locked on another thread; waiting to acquire lock...\n"); } script_interpreter->EnterSession (); ReleasePythonLock(); @@ -718,7 +711,7 @@ ScriptInterpreterPython::ExecuteInterpreterLoop () // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't // do it. - if (debugger.GetInputFileHandle() == NULL) + if (!debugger.GetInputFile().IsValid()) return; InputReaderSP reader_sp (new InputReader(debugger)); @@ -1035,21 +1028,19 @@ ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback { static StringList commands_in_progress; - FILE *out_fh = reader.GetDebugger().GetOutputFileHandle(); - if (out_fh == NULL) - out_fh = stdout; + File &out_file = reader.GetDebugger().GetOutputFile(); switch (notification) { case eInputReaderActivate: { commands_in_progress.Clear(); - if (out_fh) + if (out_file.IsValid()) { - ::fprintf (out_fh, "%s\n", g_reader_instructions); + out_file.Printf ("%s\n", g_reader_instructions); if (reader.GetPrompt()) - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush (); } } break; @@ -1058,10 +1049,10 @@ ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback break; case eInputReaderReactivate: - if (reader.GetPrompt() && out_fh) + if (reader.GetPrompt() && out_file.IsValid()) { - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush (); } break; @@ -1069,10 +1060,10 @@ ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback { std::string temp_string (bytes, bytes_len); commands_in_progress.AppendString (temp_string.c_str()); - if (out_fh && !reader.IsDone() && reader.GetPrompt()) + if (out_file.IsValid() && !reader.IsDone() && reader.GetPrompt()) { - ::fprintf (out_fh, "%s", reader.GetPrompt()); - ::fflush (out_fh); + out_file.Printf ("%s", reader.GetPrompt()); + out_file.Flush (); } } break; @@ -1108,7 +1099,7 @@ ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback } } else - ::fprintf (out_fh, "Warning: No command attached to breakpoint.\n"); + out_file.Printf ("Warning: No command attached to breakpoint.\n"); } else { |