Index: lldb/trunk/include/lldb/Host/File.h =================================================================== --- lldb/trunk/include/lldb/Host/File.h +++ lldb/trunk/include/lldb/Host/File.h @@ -120,7 +120,19 @@ Status Close() override; - void Clear(); + /// DEPRECATED! Extract the underlying FILE* and reset this File without closing it. + /// + /// This is only here to support legacy SB interfaces that need to convert scripting + /// language objects into FILE* streams. That conversion is inherently sketchy and + /// doing so may cause the stream to be leaked. + /// + /// After calling this the File will be reset to its original state. It will be + /// invalid and it will not hold on to any resources. + /// + /// \return + /// The underlying FILE* stream from this File, if one exists and can be extracted, + /// nullptr otherwise. + FILE *TakeStreamAndClear(); int GetDescriptor() const; Index: lldb/trunk/scripts/Python/python-typemaps.swig =================================================================== --- lldb/trunk/scripts/Python/python-typemaps.swig +++ lldb/trunk/scripts/Python/python-typemaps.swig @@ -372,6 +372,9 @@ $1 = $1 || PyCallable_Check(reinterpret_cast($input)); } +// FIXME both of these paths wind up calling fdopen() with no provision for ever calling +// fclose() on the result. SB interfaces that use FILE* should be deprecated for scripting +// use and this typemap should eventually be removed. %typemap(in) FILE * { using namespace lldb_private; if ($input == Py_None) @@ -398,9 +401,7 @@ lldb::FileUP file = py_file.GetUnderlyingFile(); if (!file) return nullptr; - $1 = file->GetStream(); - if ($1) - file->Clear(); + $1 = file->TakeStreamAndClear(); } } Index: lldb/trunk/source/Host/common/File.cpp =================================================================== --- lldb/trunk/source/Host/common/File.cpp +++ lldb/trunk/source/Host/common/File.cpp @@ -162,13 +162,16 @@ return error; } -void File::Clear() { - m_stream = nullptr; +FILE *File::TakeStreamAndClear() { + FILE *stream = GetStream(); + m_stream = NULL; m_descriptor = kInvalidDescriptor; m_options = 0; m_own_stream = false; + m_own_descriptor = false; m_is_interactive = m_supports_colors = m_is_real_terminal = eLazyBoolCalculate; + return stream; } Status File::GetFileSpec(FileSpec &file_spec) const {