diff options
| author | Greg Clayton <gclayton@apple.com> | 2011-07-02 23:21:06 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2011-07-02 23:21:06 +0000 |
| commit | 0c51ac3295ff1864d84c7c3a0096ab0b763354f9 (patch) | |
| tree | 8b29def3d987b2805321fc359dc755c0f96c6a3a /lldb/source | |
| parent | a6e593b4ebca3142dbf4c0416e78d991c3f448c7 (diff) | |
| download | bcm5719-llvm-0c51ac3295ff1864d84c7c3a0096ab0b763354f9.tar.gz bcm5719-llvm-0c51ac3295ff1864d84c7c3a0096ab0b763354f9.zip | |
When we use the "fd://%u" for file descriptors, we need to detect if this is
a file or socket. We now make a getsockopt call to check if the fd is a socket.
Also, the previous logic in the GDB communication needs to watch for success
with an error so we can deal with EAGAIN and other normal "retry" error codes.
llvm-svn: 134359
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Core/ConnectionFileDescriptor.cpp | 50 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | 19 |
2 files changed, 44 insertions, 25 deletions
diff --git a/lldb/source/Core/ConnectionFileDescriptor.cpp b/lldb/source/Core/ConnectionFileDescriptor.cpp index e367a9cf3ee..d7adc8b8bb9 100644 --- a/lldb/source/Core/ConnectionFileDescriptor.cpp +++ b/lldb/source/Core/ConnectionFileDescriptor.cpp @@ -111,8 +111,7 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) // We have what looks to be a valid file descriptor, but we // should make it is. We currently are doing this by trying to // get the flags from the file descriptor and making sure it - // isn't a bad fd. We also need to enable non blocking mode for - // the fd if it already isn't. + // isn't a bad fd. errno = 0; int flags = ::fcntl (m_fd, F_GETFL, 0); if (flags == -1 || errno == EBADF) @@ -124,11 +123,10 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) } else { - if ((flags & O_NONBLOCK) == 0) - { - flags |= O_NONBLOCK; - ::fcntl (m_fd, F_SETFL, flags); - } + // Try and get a socket option from this file descriptor to + // see if this is a socket and set m_is_socket accordingly. + int resuse; + m_is_socket = GetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, resuse) == 0; m_should_close_fd = true; return eConnectionStatusSuccess; } @@ -200,13 +198,12 @@ ConnectionFileDescriptor::Read (void *dst, if (timeout_usec == UINT32_MAX) { - if (m_is_socket) - SetSocketRecieveTimeout (0); - status = eConnectionStatusSuccess; + if (m_is_socket && SetSocketReceiveTimeout (timeout_usec)) + status = eConnectionStatusSuccess; } else { - if (m_is_socket && SetSocketRecieveTimeout (timeout_usec)) + if (m_is_socket && SetSocketReceiveTimeout (timeout_usec)) status = eConnectionStatusSuccess; else status = BytesAvailable (timeout_usec, error_ptr); @@ -215,7 +212,12 @@ ConnectionFileDescriptor::Read (void *dst, return 0; Error error; - ssize_t bytes_read = ::read (m_fd, dst, dst_len); + ssize_t bytes_read; + if (m_is_socket) + bytes_read = ::recv (m_fd, dst, dst_len, 0); + else + bytes_read = ::read (m_fd, dst, dst_len); + if (bytes_read == 0) { error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers. @@ -713,26 +715,38 @@ ConnectionFileDescriptor::SocketConnect (const char *host_and_port, Error *error return eConnectionStatusSuccess; } -int -ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value) -{ #if defined(__MINGW32__) || defined(__MINGW64__) - const char* option_value_p = static_cast<const char*>(&option_value); +typedef const char * set_socket_option_arg_type; +typedef char * get_socket_option_arg_type; #else // #if defined(__MINGW32__) || defined(__MINGW64__) - const void* option_value_p = &option_name; +typedef const void * set_socket_option_arg_type; +typedef void * get_socket_option_arg_type; #endif // #if defined(__MINGW32__) || defined(__MINGW64__) +int +ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value) +{ + get_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value); + socklen_t option_value_size = sizeof(int); + return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size); +} + +int +ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value) +{ + set_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value); return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value)); } bool -ConnectionFileDescriptor::SetSocketRecieveTimeout (uint32_t timeout_usec) +ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec) { if (m_is_socket) { // Check in case timeout for m_fd has already been set to this value if (timeout_usec == m_socket_timeout_usec) return true; + //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec); struct timeval timeout; timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 4525bc8eed2..69f97f14add 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -194,7 +194,8 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac if (CheckForPacket (NULL, 0, packet)) return packet.GetStringRef().size(); - while (IsConnected()) + bool timed_out = false; + while (IsConnected() && !timed_out) { lldb::ConnectionStatus status; size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); @@ -207,8 +208,11 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac { switch (status) { - case eConnectionStatusSuccess: case eConnectionStatusTimedOut: + timed_out = true; + break; + case eConnectionStatusSuccess: + //printf ("status = success but error = %s\n", error.AsCString("<invalid>")); break; case eConnectionStatusEndOfFile: @@ -218,9 +222,6 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac Disconnect(); break; } - - // Get out of the while loop we we finally timeout without getting any data - break; } } packet.Clear (); @@ -237,10 +238,14 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri if (src && src_len > 0) { - if (log) + if (log && log->GetVerbose()) { StreamString s; - log->Printf ("GDBRemoteCommunication::%s adding %zu bytes: %s\n",__FUNCTION__, src_len, src); + log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s", + __FUNCTION__, + (uint32_t)src_len, + (uint32_t)src_len, + src); } m_bytes.append ((const char *)src, src_len); } |

