ConnectionFileDescriptorPosix.cpp revision 309124
1//===-- ConnectionFileDescriptorPosix.cpp -----------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#if defined(__APPLE__) 11// Enable this special support for Apple builds where we can have unlimited 12// select bounds. We tried switching to poll() and kqueue and we were panicing 13// the kernel, so we have to stick with select for now. 14#define _DARWIN_UNLIMITED_SELECT 15#endif 16 17#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" 18#include "lldb/Host/Config.h" 19#include "lldb/Host/IOObject.h" 20#include "lldb/Host/SocketAddress.h" 21#include "lldb/Host/Socket.h" 22#include "lldb/Host/StringConvert.h" 23 24// C Includes 25#include <errno.h> 26#include <fcntl.h> 27#include <string.h> 28#include <stdlib.h> 29#include <sys/types.h> 30 31#ifndef LLDB_DISABLE_POSIX 32#include <termios.h> 33#endif 34 35// C++ Includes 36#include <sstream> 37 38// Other libraries and framework includes 39#include "llvm/Support/ErrorHandling.h" 40#if defined(__APPLE__) 41#include "llvm/ADT/SmallVector.h" 42#endif 43// Project includes 44#include "lldb/Core/Communication.h" 45#include "lldb/Core/Log.h" 46#include "lldb/Core/StreamString.h" 47#include "lldb/Core/Timer.h" 48#include "lldb/Host/Host.h" 49#include "lldb/Host/Socket.h" 50#include "lldb/Host/common/TCPSocket.h" 51#include "lldb/Interpreter/Args.h" 52 53using namespace lldb; 54using namespace lldb_private; 55 56const char* ConnectionFileDescriptor::LISTEN_SCHEME = "listen"; 57const char* ConnectionFileDescriptor::ACCEPT_SCHEME = "accept"; 58const char* ConnectionFileDescriptor::UNIX_ACCEPT_SCHEME = "unix-accept"; 59const char* ConnectionFileDescriptor::CONNECT_SCHEME = "connect"; 60const char* ConnectionFileDescriptor::TCP_CONNECT_SCHEME = "tcp-connect"; 61const char* ConnectionFileDescriptor::UDP_SCHEME = "udp"; 62const char* ConnectionFileDescriptor::UNIX_CONNECT_SCHEME = "unix-connect"; 63const char* ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME = "unix-abstract-connect"; 64const char* ConnectionFileDescriptor::FD_SCHEME = "fd"; 65const char* ConnectionFileDescriptor::FILE_SCHEME = "file"; 66 67namespace { 68 69const char* 70GetURLAddress(const char *url, const char *scheme) 71{ 72 const auto prefix = std::string(scheme) + "://"; 73 if (strstr(url, prefix.c_str()) != url) 74 return nullptr; 75 76 return url + prefix.size(); 77} 78 79} 80 81ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit) 82 : Connection(), 83 m_pipe(), 84 m_mutex(), 85 m_shutting_down(false), 86 m_waiting_for_accept(false), 87 m_child_processes_inherit(child_processes_inherit) 88{ 89 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); 90 if (log) 91 log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", static_cast<void *>(this)); 92} 93 94ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd) 95 : Connection(), 96 m_pipe(), 97 m_mutex(), 98 m_shutting_down(false), 99 m_waiting_for_accept(false), 100 m_child_processes_inherit(false) 101{ 102 m_write_sp.reset(new File(fd, owns_fd)); 103 m_read_sp.reset(new File(fd, false)); 104 105 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); 106 if (log) 107 log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", 108 static_cast<void *>(this), fd, owns_fd); 109 OpenCommandPipe(); 110} 111 112ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket) 113 : Connection(), 114 m_pipe(), 115 m_mutex(), 116 m_shutting_down(false), 117 m_waiting_for_accept(false), 118 m_child_processes_inherit(false) 119{ 120 InitializeSocket(socket); 121} 122 123ConnectionFileDescriptor::~ConnectionFileDescriptor() 124{ 125 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); 126 if (log) 127 log->Printf("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", static_cast<void *>(this)); 128 Disconnect(NULL); 129 CloseCommandPipe(); 130} 131 132void 133ConnectionFileDescriptor::OpenCommandPipe() 134{ 135 CloseCommandPipe(); 136 137 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 138 // Make the command file descriptor here: 139 Error result = m_pipe.CreateNew(m_child_processes_inherit); 140 if (!result.Success()) 141 { 142 if (log) 143 log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe () - could not make pipe: %s", static_cast<void *>(this), 144 result.AsCString()); 145 } 146 else 147 { 148 if (log) 149 log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe() - success readfd=%d writefd=%d", static_cast<void *>(this), 150 m_pipe.GetReadFileDescriptor(), m_pipe.GetWriteFileDescriptor()); 151 } 152} 153 154void 155ConnectionFileDescriptor::CloseCommandPipe() 156{ 157 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 158 if (log) 159 log->Printf("%p ConnectionFileDescriptor::CloseCommandPipe()", static_cast<void *>(this)); 160 161 m_pipe.Close(); 162} 163 164bool 165ConnectionFileDescriptor::IsConnected() const 166{ 167 return (m_read_sp && m_read_sp->IsValid()) || (m_write_sp && m_write_sp->IsValid()); 168} 169 170ConnectionStatus 171ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr) 172{ 173 std::lock_guard<std::recursive_mutex> guard(m_mutex); 174 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 175 if (log) 176 log->Printf("%p ConnectionFileDescriptor::Connect (url = '%s')", static_cast<void *>(this), s); 177 178 OpenCommandPipe(); 179 180 if (s && s[0]) 181 { 182 const char *addr = nullptr; 183 if ((addr = GetURLAddress(s, LISTEN_SCHEME))) 184 { 185 // listen://HOST:PORT 186 return SocketListenAndAccept(addr, error_ptr); 187 } 188 else if ((addr = GetURLAddress(s, ACCEPT_SCHEME))) 189 { 190 // unix://SOCKNAME 191 return NamedSocketAccept(addr, error_ptr); 192 } 193 else if ((addr = GetURLAddress(s, UNIX_ACCEPT_SCHEME))) 194 { 195 // unix://SOCKNAME 196 return NamedSocketAccept(addr, error_ptr); 197 } 198 else if ((addr = GetURLAddress(s, CONNECT_SCHEME))) 199 { 200 return ConnectTCP(addr, error_ptr); 201 } 202 else if ((addr = GetURLAddress(s, TCP_CONNECT_SCHEME))) 203 { 204 return ConnectTCP(addr, error_ptr); 205 } 206 else if ((addr = GetURLAddress(s, UDP_SCHEME))) 207 { 208 return ConnectUDP(addr, error_ptr); 209 } 210 else if ((addr = GetURLAddress(s, UNIX_CONNECT_SCHEME))) 211 { 212 // unix-connect://SOCKNAME 213 return NamedSocketConnect(addr, error_ptr); 214 } 215 else if ((addr = GetURLAddress(s, UNIX_ABSTRACT_CONNECT_SCHEME))) 216 { 217 // unix-abstract-connect://SOCKNAME 218 return UnixAbstractSocketConnect(addr, error_ptr); 219 } 220#ifndef LLDB_DISABLE_POSIX 221 else if ((addr = GetURLAddress(s, FD_SCHEME))) 222 { 223 // Just passing a native file descriptor within this current process 224 // that is already opened (possibly from a service or other source). 225 bool success = false; 226 int fd = StringConvert::ToSInt32(addr, -1, 0, &success); 227 228 if (success) 229 { 230 // We have what looks to be a valid file descriptor, but we 231 // should make sure it is. We currently are doing this by trying to 232 // get the flags from the file descriptor and making sure it 233 // isn't a bad fd. 234 errno = 0; 235 int flags = ::fcntl(fd, F_GETFL, 0); 236 if (flags == -1 || errno == EBADF) 237 { 238 if (error_ptr) 239 error_ptr->SetErrorStringWithFormat("stale file descriptor: %s", s); 240 m_read_sp.reset(); 241 m_write_sp.reset(); 242 return eConnectionStatusError; 243 } 244 else 245 { 246 // Don't take ownership of a file descriptor that gets passed 247 // to us since someone else opened the file descriptor and 248 // handed it to us. 249 // TODO: Since are using a URL to open connection we should 250 // eventually parse options using the web standard where we 251 // have "fd://123?opt1=value;opt2=value" and we can have an 252 // option be "owns=1" or "owns=0" or something like this to 253 // allow us to specify this. For now, we assume we must 254 // assume we don't own it. 255 256 std::unique_ptr<TCPSocket> tcp_socket; 257 tcp_socket.reset(new TCPSocket(fd, false)); 258 // Try and get a socket option from this file descriptor to 259 // see if this is a socket and set m_is_socket accordingly. 260 int resuse; 261 bool is_socket = !!tcp_socket->GetOption(SOL_SOCKET, SO_REUSEADDR, resuse); 262 if (is_socket) 263 { 264 m_read_sp = std::move(tcp_socket); 265 m_write_sp = m_read_sp; 266 } 267 else 268 { 269 m_read_sp.reset(new File(fd, false)); 270 m_write_sp.reset(new File(fd, false)); 271 } 272 m_uri.assign(addr); 273 return eConnectionStatusSuccess; 274 } 275 } 276 277 if (error_ptr) 278 error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"%s\"", s); 279 m_read_sp.reset(); 280 m_write_sp.reset(); 281 return eConnectionStatusError; 282 } 283 else if ((addr = GetURLAddress(s, FILE_SCHEME))) 284 { 285 // file:///PATH 286 const char *path = addr; 287 int fd = -1; 288 do 289 { 290 fd = ::open(path, O_RDWR); 291 } while (fd == -1 && errno == EINTR); 292 293 if (fd == -1) 294 { 295 if (error_ptr) 296 error_ptr->SetErrorToErrno(); 297 return eConnectionStatusError; 298 } 299 300 if (::isatty(fd)) 301 { 302 // Set up serial terminal emulation 303 struct termios options; 304 ::tcgetattr(fd, &options); 305 306 // Set port speed to maximum 307 ::cfsetospeed(&options, B115200); 308 ::cfsetispeed(&options, B115200); 309 310 // Raw input, disable echo and signals 311 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 312 313 // Make sure only one character is needed to return from a read 314 options.c_cc[VMIN] = 1; 315 options.c_cc[VTIME] = 0; 316 317 ::tcsetattr(fd, TCSANOW, &options); 318 } 319 320 int flags = ::fcntl(fd, F_GETFL, 0); 321 if (flags >= 0) 322 { 323 if ((flags & O_NONBLOCK) == 0) 324 { 325 flags |= O_NONBLOCK; 326 ::fcntl(fd, F_SETFL, flags); 327 } 328 } 329 m_read_sp.reset(new File(fd, true)); 330 m_write_sp.reset(new File(fd, false)); 331 return eConnectionStatusSuccess; 332 } 333#endif 334 if (error_ptr) 335 error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'", s); 336 return eConnectionStatusError; 337 } 338 if (error_ptr) 339 error_ptr->SetErrorString("invalid connect arguments"); 340 return eConnectionStatusError; 341} 342 343bool 344ConnectionFileDescriptor::InterruptRead() 345{ 346 size_t bytes_written = 0; 347 Error result = m_pipe.Write("i", 1, bytes_written); 348 return result.Success(); 349} 350 351ConnectionStatus 352ConnectionFileDescriptor::Disconnect(Error *error_ptr) 353{ 354 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 355 if (log) 356 log->Printf("%p ConnectionFileDescriptor::Disconnect ()", static_cast<void *>(this)); 357 358 ConnectionStatus status = eConnectionStatusSuccess; 359 360 if (!IsConnected()) 361 { 362 if (log) 363 log->Printf("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", static_cast<void *>(this)); 364 return eConnectionStatusSuccess; 365 } 366 367 if (m_read_sp && m_read_sp->IsValid() && m_read_sp->GetFdType() == IOObject::eFDTypeSocket) 368 static_cast<Socket &>(*m_read_sp).PreDisconnect(); 369 370 // Try to get the ConnectionFileDescriptor's mutex. If we fail, that is quite likely 371 // because somebody is doing a blocking read on our file descriptor. If that's the case, 372 // then send the "q" char to the command file channel so the read will wake up and the connection 373 // will then know to shut down. 374 375 m_shutting_down = true; 376 377 std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock); 378 if (!locker.try_lock()) 379 { 380 if (m_pipe.CanWrite()) 381 { 382 size_t bytes_written = 0; 383 Error result = m_pipe.Write("q", 1, bytes_written); 384 if (log) 385 log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, sent 'q' to %d, error = '%s'.", 386 static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(), result.AsCString()); 387 } 388 else if (log) 389 { 390 log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.", 391 static_cast<void *>(this)); 392 } 393 locker.lock(); 394 } 395 396 Error error = m_read_sp->Close(); 397 Error error2 = m_write_sp->Close(); 398 if (error.Fail() || error2.Fail()) 399 status = eConnectionStatusError; 400 if (error_ptr) 401 *error_ptr = error.Fail() ? error : error2; 402 403 // Close any pipes we were using for async interrupts 404 m_pipe.Close(); 405 406 m_uri.clear(); 407 m_shutting_down = false; 408 return status; 409} 410 411size_t 412ConnectionFileDescriptor::Read(void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr) 413{ 414 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 415 416 std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock); 417 if (!locker.try_lock()) 418 { 419 if (log) 420 log->Printf("%p ConnectionFileDescriptor::Read () failed to get the connection lock.", static_cast<void *>(this)); 421 if (error_ptr) 422 error_ptr->SetErrorString("failed to get the connection lock for read."); 423 424 status = eConnectionStatusTimedOut; 425 return 0; 426 } 427 428 if (m_shutting_down) 429 { 430 status = eConnectionStatusError; 431 return 0; 432 } 433 434 status = BytesAvailable(timeout_usec, error_ptr); 435 if (status != eConnectionStatusSuccess) 436 return 0; 437 438 Error error; 439 size_t bytes_read = dst_len; 440 error = m_read_sp->Read(dst, bytes_read); 441 442 if (log) 443 { 444 log->Printf("%p ConnectionFileDescriptor::Read() fd = %" PRIu64 ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s", 445 static_cast<void *>(this), static_cast<uint64_t>(m_read_sp->GetWaitableHandle()), static_cast<void *>(dst), 446 static_cast<uint64_t>(dst_len), static_cast<uint64_t>(bytes_read), error.AsCString()); 447 } 448 449 if (bytes_read == 0) 450 { 451 error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers. 452 status = eConnectionStatusEndOfFile; 453 } 454 455 if (error_ptr) 456 *error_ptr = error; 457 458 if (error.Fail()) 459 { 460 uint32_t error_value = error.GetError(); 461 switch (error_value) 462 { 463 case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read. 464 if (m_read_sp->GetFdType() == IOObject::eFDTypeSocket) 465 status = eConnectionStatusTimedOut; 466 else 467 status = eConnectionStatusSuccess; 468 return 0; 469 470 case EFAULT: // Buf points outside the allocated address space. 471 case EINTR: // A read from a slow device was interrupted before any data arrived by the delivery of a signal. 472 case EINVAL: // The pointer associated with fildes was negative. 473 case EIO: // An I/O error occurred while reading from the file system. 474 // The process group is orphaned. 475 // The file is a regular file, nbyte is greater than 0, 476 // the starting position is before the end-of-file, and 477 // the starting position is greater than or equal to the 478 // offset maximum established for the open file 479 // descriptor associated with fildes. 480 case EISDIR: // An attempt is made to read a directory. 481 case ENOBUFS: // An attempt to allocate a memory buffer fails. 482 case ENOMEM: // Insufficient memory is available. 483 status = eConnectionStatusError; 484 break; // Break to close.... 485 486 case ENOENT: // no such file or directory 487 case EBADF: // fildes is not a valid file or socket descriptor open for reading. 488 case ENXIO: // An action is requested of a device that does not exist.. 489 // A requested action cannot be performed by the device. 490 case ECONNRESET: // The connection is closed by the peer during a read attempt on a socket. 491 case ENOTCONN: // A read is attempted on an unconnected socket. 492 status = eConnectionStatusLostConnection; 493 break; // Break to close.... 494 495 case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket. 496 status = eConnectionStatusTimedOut; 497 return 0; 498 499 default: 500 if (log) 501 log->Printf("%p ConnectionFileDescriptor::Read (), unexpected error: %s", static_cast<void *>(this), 502 strerror(error_value)); 503 status = eConnectionStatusError; 504 break; // Break to close.... 505 } 506 507 return 0; 508 } 509 return bytes_read; 510} 511 512size_t 513ConnectionFileDescriptor::Write(const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) 514{ 515 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 516 if (log) 517 log->Printf("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", static_cast<void *>(this), 518 static_cast<const void *>(src), static_cast<uint64_t>(src_len)); 519 520 if (!IsConnected()) 521 { 522 if (error_ptr) 523 error_ptr->SetErrorString("not connected"); 524 status = eConnectionStatusNoConnection; 525 return 0; 526 } 527 528 Error error; 529 530 size_t bytes_sent = src_len; 531 error = m_write_sp->Write(src, bytes_sent); 532 533 if (log) 534 { 535 log->Printf("%p ConnectionFileDescriptor::Write(fd = %" PRIu64 ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)", 536 static_cast<void *>(this), static_cast<uint64_t>(m_write_sp->GetWaitableHandle()), static_cast<const void *>(src), 537 static_cast<uint64_t>(src_len), static_cast<uint64_t>(bytes_sent), error.AsCString()); 538 } 539 540 if (error_ptr) 541 *error_ptr = error; 542 543 if (error.Fail()) 544 { 545 switch (error.GetError()) 546 { 547 case EAGAIN: 548 case EINTR: 549 status = eConnectionStatusSuccess; 550 return 0; 551 552 case ECONNRESET: // The connection is closed by the peer during a read attempt on a socket. 553 case ENOTCONN: // A read is attempted on an unconnected socket. 554 status = eConnectionStatusLostConnection; 555 break; // Break to close.... 556 557 default: 558 status = eConnectionStatusError; 559 break; // Break to close.... 560 } 561 562 return 0; 563 } 564 565 status = eConnectionStatusSuccess; 566 return bytes_sent; 567} 568 569std::string 570ConnectionFileDescriptor::GetURI() 571{ 572 return m_uri; 573} 574 575// This ConnectionFileDescriptor::BytesAvailable() uses select(). 576// 577// PROS: 578// - select is consistent across most unix platforms 579// - The Apple specific version allows for unlimited fds in the fd_sets by 580// setting the _DARWIN_UNLIMITED_SELECT define prior to including the 581// required header files. 582// CONS: 583// - on non-Apple platforms, only supports file descriptors up to FD_SETSIZE. 584// This implementation will assert if it runs into that hard limit to let 585// users know that another ConnectionFileDescriptor::BytesAvailable() should 586// be used or a new version of ConnectionFileDescriptor::BytesAvailable() 587// should be written for the system that is running into the limitations. 588 589#if defined(__APPLE__) 590#define FD_SET_DATA(fds) fds.data() 591#else 592#define FD_SET_DATA(fds) &fds 593#endif 594 595ConnectionStatus 596ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr) 597{ 598 // Don't need to take the mutex here separately since we are only called from Read. If we 599 // ever get used more generally we will need to lock here as well. 600 601 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION)); 602 if (log) 603 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", static_cast<void *>(this), timeout_usec); 604 605 struct timeval *tv_ptr; 606 struct timeval tv; 607 if (timeout_usec == UINT32_MAX) 608 { 609 // Inifinite wait... 610 tv_ptr = nullptr; 611 } 612 else 613 { 614 TimeValue time_value; 615 time_value.OffsetWithMicroSeconds(timeout_usec); 616 tv.tv_sec = time_value.seconds(); 617 tv.tv_usec = time_value.microseconds(); 618 tv_ptr = &tv; 619 } 620 621 // Make a copy of the file descriptors to make sure we don't 622 // have another thread change these values out from under us 623 // and cause problems in the loop below where like in FS_SET() 624 const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle(); 625 const int pipe_fd = m_pipe.GetReadFileDescriptor(); 626 627 if (handle != IOObject::kInvalidHandleValue) 628 { 629#if defined(_MSC_VER) 630 // select() won't accept pipes on Windows. The entire Windows codepath needs to be 631 // converted over to using WaitForMultipleObjects and event HANDLEs, but for now at least 632 // this will allow ::select() to not return an error. 633 const bool have_pipe_fd = false; 634#else 635 const bool have_pipe_fd = pipe_fd >= 0; 636#if !defined(__APPLE__) 637 assert(handle < FD_SETSIZE); 638 if (have_pipe_fd) 639 assert(pipe_fd < FD_SETSIZE); 640#endif 641#endif 642 while (handle == m_read_sp->GetWaitableHandle()) 643 { 644 const int nfds = std::max<int>(handle, pipe_fd) + 1; 645#if defined(__APPLE__) 646 llvm::SmallVector<fd_set, 1> read_fds; 647 read_fds.resize((nfds / FD_SETSIZE) + 1); 648 for (size_t i = 0; i < read_fds.size(); ++i) 649 FD_ZERO(&read_fds[i]); 650// FD_SET doesn't bounds check, it just happily walks off the end 651// but we have taken care of making the extra storage with our 652// SmallVector of fd_set objects 653#else 654 fd_set read_fds; 655 FD_ZERO(&read_fds); 656#endif 657 FD_SET(handle, FD_SET_DATA(read_fds)); 658 if (have_pipe_fd) 659 FD_SET(pipe_fd, FD_SET_DATA(read_fds)); 660 661 Error error; 662 663 if (log) 664 { 665 if (have_pipe_fd) 666 log->Printf( 667 "%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...", 668 static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr)); 669 else 670 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...", 671 static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr)); 672 } 673 674 const int num_set_fds = ::select(nfds, FD_SET_DATA(read_fds), NULL, NULL, tv_ptr); 675 if (num_set_fds < 0) 676 error.SetErrorToErrno(); 677 else 678 error.Clear(); 679 680 if (log) 681 { 682 if (have_pipe_fd) 683 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) " 684 "=> %d, error = %s", 685 static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr), num_set_fds, 686 error.AsCString()); 687 else 688 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => " 689 "%d, error = %s", 690 static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr), num_set_fds, error.AsCString()); 691 } 692 693 if (error_ptr) 694 *error_ptr = error; 695 696 if (error.Fail()) 697 { 698 switch (error.GetError()) 699 { 700 case EBADF: // One of the descriptor sets specified an invalid descriptor. 701 return eConnectionStatusLostConnection; 702 703 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. 704 default: // Other unknown error 705 return eConnectionStatusError; 706 707 case EAGAIN: // The kernel was (perhaps temporarily) unable to 708 // allocate the requested number of file descriptors, 709 // or we have non-blocking IO 710 case EINTR: // A signal was delivered before the time limit 711 // expired and before any of the selected events 712 // occurred. 713 break; // Lets keep reading to until we timeout 714 } 715 } 716 else if (num_set_fds == 0) 717 { 718 return eConnectionStatusTimedOut; 719 } 720 else if (num_set_fds > 0) 721 { 722 if (FD_ISSET(handle, FD_SET_DATA(read_fds))) 723 return eConnectionStatusSuccess; 724 if (have_pipe_fd && FD_ISSET(pipe_fd, FD_SET_DATA(read_fds))) 725 { 726 // There is an interrupt or exit command in the command pipe 727 // Read the data from that pipe: 728 char buffer[1]; 729 730 ssize_t bytes_read; 731 732 do 733 { 734 bytes_read = ::read(pipe_fd, buffer, sizeof(buffer)); 735 } while (bytes_read < 0 && errno == EINTR); 736 737 switch (buffer[0]) 738 { 739 case 'q': 740 if (log) 741 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() " 742 "got data: %c from the command channel.", 743 static_cast<void *>(this), buffer[0]); 744 return eConnectionStatusEndOfFile; 745 case 'i': 746 // Interrupt the current read 747 return eConnectionStatusInterrupted; 748 } 749 } 750 } 751 } 752 } 753 754 if (error_ptr) 755 error_ptr->SetErrorString("not connected"); 756 return eConnectionStatusLostConnection; 757} 758 759ConnectionStatus 760ConnectionFileDescriptor::NamedSocketAccept(const char *socket_name, Error *error_ptr) 761{ 762 Socket *socket = nullptr; 763 Error error = Socket::UnixDomainAccept(socket_name, m_child_processes_inherit, socket); 764 if (error_ptr) 765 *error_ptr = error; 766 m_write_sp.reset(socket); 767 m_read_sp = m_write_sp; 768 if (error.Fail()) 769 { 770 return eConnectionStatusError; 771 } 772 m_uri.assign(socket_name); 773 return eConnectionStatusSuccess; 774} 775 776ConnectionStatus 777ConnectionFileDescriptor::NamedSocketConnect(const char *socket_name, Error *error_ptr) 778{ 779 Socket *socket = nullptr; 780 Error error = Socket::UnixDomainConnect(socket_name, m_child_processes_inherit, socket); 781 if (error_ptr) 782 *error_ptr = error; 783 m_write_sp.reset(socket); 784 m_read_sp = m_write_sp; 785 if (error.Fail()) 786 { 787 return eConnectionStatusError; 788 } 789 m_uri.assign(socket_name); 790 return eConnectionStatusSuccess; 791} 792 793lldb::ConnectionStatus 794ConnectionFileDescriptor::UnixAbstractSocketConnect(const char *socket_name, Error *error_ptr) 795{ 796 Socket *socket = nullptr; 797 Error error = Socket::UnixAbstractConnect(socket_name, m_child_processes_inherit, socket); 798 if (error_ptr) 799 *error_ptr = error; 800 m_write_sp.reset(socket); 801 m_read_sp = m_write_sp; 802 if (error.Fail()) 803 { 804 return eConnectionStatusError; 805 } 806 m_uri.assign(socket_name); 807 return eConnectionStatusSuccess; 808} 809 810ConnectionStatus 811ConnectionFileDescriptor::SocketListenAndAccept(const char *s, Error *error_ptr) 812{ 813 m_port_predicate.SetValue(0, eBroadcastNever); 814 815 Socket *socket = nullptr; 816 m_waiting_for_accept = true; 817 Error error = Socket::TcpListen(s, m_child_processes_inherit, socket, &m_port_predicate); 818 if (error_ptr) 819 *error_ptr = error; 820 if (error.Fail()) 821 return eConnectionStatusError; 822 823 std::unique_ptr<Socket> listening_socket_up; 824 825 listening_socket_up.reset(socket); 826 socket = nullptr; 827 error = listening_socket_up->Accept(s, m_child_processes_inherit, socket); 828 listening_socket_up.reset(); 829 if (error_ptr) 830 *error_ptr = error; 831 if (error.Fail()) 832 return eConnectionStatusError; 833 834 InitializeSocket(socket); 835 return eConnectionStatusSuccess; 836} 837 838ConnectionStatus 839ConnectionFileDescriptor::ConnectTCP(const char *s, Error *error_ptr) 840{ 841 Socket *socket = nullptr; 842 Error error = Socket::TcpConnect(s, m_child_processes_inherit, socket); 843 if (error_ptr) 844 *error_ptr = error; 845 m_write_sp.reset(socket); 846 m_read_sp = m_write_sp; 847 if (error.Fail()) 848 { 849 return eConnectionStatusError; 850 } 851 m_uri.assign(s); 852 return eConnectionStatusSuccess; 853} 854 855ConnectionStatus 856ConnectionFileDescriptor::ConnectUDP(const char *s, Error *error_ptr) 857{ 858 Socket *send_socket = nullptr; 859 Socket *recv_socket = nullptr; 860 Error error = Socket::UdpConnect(s, m_child_processes_inherit, send_socket, recv_socket); 861 if (error_ptr) 862 *error_ptr = error; 863 m_write_sp.reset(send_socket); 864 m_read_sp.reset(recv_socket); 865 if (error.Fail()) 866 { 867 return eConnectionStatusError; 868 } 869 m_uri.assign(s); 870 return eConnectionStatusSuccess; 871} 872 873uint16_t 874ConnectionFileDescriptor::GetListeningPort(uint32_t timeout_sec) 875{ 876 uint16_t bound_port = 0; 877 if (timeout_sec == UINT32_MAX) 878 m_port_predicate.WaitForValueNotEqualTo(0, bound_port); 879 else 880 { 881 TimeValue timeout = TimeValue::Now(); 882 timeout.OffsetWithSeconds(timeout_sec); 883 m_port_predicate.WaitForValueNotEqualTo(0, bound_port, &timeout); 884 } 885 return bound_port; 886} 887 888bool 889ConnectionFileDescriptor::GetChildProcessesInherit() const 890{ 891 return m_child_processes_inherit; 892} 893 894void 895ConnectionFileDescriptor::SetChildProcessesInherit(bool child_processes_inherit) 896{ 897 m_child_processes_inherit = child_processes_inherit; 898} 899 900void 901ConnectionFileDescriptor::InitializeSocket(Socket* socket) 902{ 903 assert(socket->GetSocketProtocol() == Socket::ProtocolTcp); 904 TCPSocket* tcp_socket = static_cast<TCPSocket*>(socket); 905 906 m_write_sp.reset(socket); 907 m_read_sp = m_write_sp; 908 StreamString strm; 909 strm.Printf("connect://%s:%u",tcp_socket->GetRemoteIPAddress().c_str(), tcp_socket->GetRemotePortNumber()); 910 m_uri.swap(strm.GetString()); 911} 912