[llvm-branch-commits] [lldb] r199920 - Make lldb_private::File safe to use when mixing "FILE *" and "fd" usage where if we call fdopen, we don't want to close the m_descriptor.
Greg Clayton
gclayton at apple.com
Thu Jan 23 10:53:01 PST 2014
Author: gclayton
Date: Thu Jan 23 12:53:01 2014
New Revision: 199920
URL: http://llvm.org/viewvc/llvm-project?rev=199920&view=rev
Log:
Make lldb_private::File safe to use when mixing "FILE *" and "fd" usage where if we call fdopen, we don't want to close the m_descriptor.
Modified:
lldb/branches/iohandler/include/lldb/Host/File.h
lldb/branches/iohandler/source/Host/common/File.cpp
Modified: lldb/branches/iohandler/include/lldb/Host/File.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/iohandler/include/lldb/Host/File.h?rev=199920&r1=199919&r2=199920&view=diff
==============================================================================
--- lldb/branches/iohandler/include/lldb/Host/File.h (original)
+++ lldb/branches/iohandler/include/lldb/Host/File.h Thu Jan 23 12:53:01 2014
@@ -51,7 +51,8 @@ public:
m_descriptor (kInvalidDescriptor),
m_stream (kInvalidStream),
m_options (0),
- m_owned (false)
+ m_own_stream (false),
+ m_own_descriptor (false)
{
}
@@ -59,7 +60,8 @@ public:
m_descriptor (kInvalidDescriptor),
m_stream (fh),
m_options (0),
- m_owned (transfer_ownership)
+ m_own_stream (transfer_ownership),
+ m_own_descriptor (false)
{
}
@@ -111,13 +113,15 @@ public:
uint32_t options,
uint32_t permissions = lldb::eFilePermissionsFileDefault);
- File (int fd, bool tranfer_ownership) :
+ File (int fd, bool transfer_ownership) :
m_descriptor (fd),
m_stream (kInvalidStream),
m_options (0),
- m_owned (tranfer_ownership)
+ m_own_stream (false),
+ m_own_descriptor (transfer_ownership)
{
}
+
//------------------------------------------------------------------
/// Destructor.
///
@@ -503,7 +507,8 @@ protected:
int m_descriptor;
FILE *m_stream;
uint32_t m_options;
- bool m_owned;
+ bool m_own_stream;
+ bool m_own_descriptor;
};
} // namespace lldb_private
Modified: lldb/branches/iohandler/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/iohandler/source/Host/common/File.cpp?rev=199920&r1=199919&r2=199920&view=diff
==============================================================================
--- lldb/branches/iohandler/source/Host/common/File.cpp (original)
+++ lldb/branches/iohandler/source/Host/common/File.cpp Thu Jan 23 12:53:01 2014
@@ -77,7 +77,8 @@ File::File(const char *path, uint32_t op
m_descriptor (kInvalidDescriptor),
m_stream (kInvalidStream),
m_options (),
- m_owned (false)
+ m_own_stream (false),
+ m_own_descriptor (false)
{
Open (path, options, permissions);
}
@@ -88,7 +89,8 @@ File::File (const FileSpec& filespec,
m_descriptor (kInvalidDescriptor),
m_stream (kInvalidStream),
m_options (0),
- m_owned (false)
+ m_own_stream (false),
+ m_own_descriptor (false)
{
if (filespec)
{
@@ -100,7 +102,8 @@ File::File (const File &rhs) :
m_descriptor (kInvalidDescriptor),
m_stream (kInvalidStream),
m_options (0),
- m_owned (false)
+ m_own_stream (false),
+ m_own_descriptor (false)
{
Duplicate (rhs);
}
@@ -141,7 +144,7 @@ File::SetDescriptor (int fd, bool transf
if (IsValid())
Close();
m_descriptor = fd;
- m_owned = transfer_ownership;
+ m_own_descriptor = transfer_ownership;
}
@@ -155,10 +158,31 @@ File::GetStream ()
const char *mode = GetStreamOpenModeFromOptions (m_options);
if (mode)
{
+ if (!m_own_descriptor)
+ {
+ // We must duplicate the file descriptor if we don't own it because
+ // when you call fdopen, the stream will own the fd
+#ifdef _WIN32
+ m_descriptor = ::_dup(GetDescriptor());
+#else
+ m_descriptor = ::fcntl(GetDescriptor(), F_DUPFD);
+#endif
+ m_own_descriptor = true;
+ }
+
do
{
m_stream = ::fdopen (m_descriptor, mode);
} while (m_stream == NULL && errno == EINTR);
+
+ // If we got a stream, then we own the stream and should no
+ // longer own the descriptor because fclose() will close it for us
+
+ if (m_stream)
+ {
+ m_own_stream = true;
+ m_own_descriptor = false;
+ }
}
}
}
@@ -172,7 +196,7 @@ File::SetStream (FILE *fh, bool transfer
if (IsValid())
Close();
m_stream = fh;
- m_owned = transfer_ownership;
+ m_own_stream = transfer_ownership;
}
Error
@@ -194,7 +218,7 @@ File::Duplicate (const File &rhs)
else
{
m_options = rhs.m_options;
- m_owned = true;
+ m_own_descriptor = true;
}
}
else
@@ -273,7 +297,7 @@ File::Open (const char *path, uint32_t o
error.SetErrorToErrno();
else
{
- m_owned = true;
+ m_own_descriptor = true;
m_options = options;
}
@@ -331,27 +355,22 @@ Error
File::Close ()
{
Error error;
- if (IsValid ())
+ if (StreamIsValid() && m_own_stream)
{
- 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;
+ if (::fclose (m_stream) == EOF)
+ error.SetErrorToErrno();
+ }
+
+ if (DescriptorIsValid() && m_own_descriptor)
+ {
+ if (::close (m_descriptor) != 0)
+ error.SetErrorToErrno();
}
+ m_descriptor = kInvalidDescriptor;
+ m_stream = kInvalidStream;
+ m_options = 0;
+ m_own_stream = false;
+ m_own_descriptor = false;
return error;
}
More information about the llvm-branch-commits
mailing list