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