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