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 const Timeout<std::micro> &timeout, 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, 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 557 ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout, 558 Error *error_ptr) { 559 // Don't need to take the mutex here separately since we are only called from 560 // Read. If we 561 // ever get used more generally we will need to lock here as well. 562 563 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION)); 564 if (log) 565 log->Printf( 566 "%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %lu)", 567 static_cast<void *>(this), long(timeout ? timeout->count() : -1)); 568 569 // Make a copy of the file descriptors to make sure we don't 570 // have another thread change these values out from under us 571 // and cause problems in the loop below where like in FS_SET() 572 const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle(); 573 const int pipe_fd = m_pipe.GetReadFileDescriptor(); 574 575 if (handle != IOObject::kInvalidHandleValue) { 576 SelectHelper select_helper; 577 if (timeout) 578 select_helper.SetTimeout(*timeout); 579 580 select_helper.FDSetRead(handle); 581 #if defined(_MSC_VER) 582 // select() won't accept pipes on Windows. The entire Windows codepath 583 // needs to be 584 // converted over to using WaitForMultipleObjects and event HANDLEs, but for 585 // now at least 586 // this will allow ::select() to not return an error. 587 const bool have_pipe_fd = false; 588 #else 589 const bool have_pipe_fd = pipe_fd >= 0; 590 #endif 591 if (have_pipe_fd) 592 select_helper.FDSetRead(pipe_fd); 593 594 while (handle == m_read_sp->GetWaitableHandle()) { 595 596 Error error = select_helper.Select(); 597 598 if (error_ptr) 599 *error_ptr = error; 600 601 if (error.Fail()) { 602 switch (error.GetError()) { 603 case EBADF: // One of the descriptor sets specified an invalid 604 // descriptor. 605 return eConnectionStatusLostConnection; 606 607 case EINVAL: // The specified time limit is invalid. One of its 608 // components is negative or too large. 609 default: // Other unknown error 610 return eConnectionStatusError; 611 612 case ETIMEDOUT: 613 return eConnectionStatusTimedOut; 614 615 case EAGAIN: // The kernel was (perhaps temporarily) unable to 616 // allocate the requested number of file descriptors, 617 // or we have non-blocking IO 618 case EINTR: // A signal was delivered before the time limit 619 // expired and before any of the selected events 620 // occurred. 621 break; // Lets keep reading to until we timeout 622 } 623 } else { 624 if (select_helper.FDIsSetRead(handle)) 625 return eConnectionStatusSuccess; 626 627 if (select_helper.FDIsSetRead(pipe_fd)) { 628 // There is an interrupt or exit command in the command pipe 629 // Read the data from that pipe: 630 char buffer[1]; 631 632 ssize_t bytes_read; 633 634 do { 635 bytes_read = ::read(pipe_fd, buffer, sizeof(buffer)); 636 } while (bytes_read < 0 && errno == EINTR); 637 638 switch (buffer[0]) { 639 case 'q': 640 if (log) 641 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() " 642 "got data: %c from the command channel.", 643 static_cast<void *>(this), buffer[0]); 644 return eConnectionStatusEndOfFile; 645 case 'i': 646 // Interrupt the current read 647 return eConnectionStatusInterrupted; 648 } 649 } 650 } 651 } 652 } 653 654 if (error_ptr) 655 error_ptr->SetErrorString("not connected"); 656 return eConnectionStatusLostConnection; 657 } 658 659 ConnectionStatus 660 ConnectionFileDescriptor::NamedSocketAccept(llvm::StringRef socket_name, 661 Error *error_ptr) { 662 Socket *socket = nullptr; 663 Error error = 664 Socket::UnixDomainAccept(socket_name, m_child_processes_inherit, socket); 665 if (error_ptr) 666 *error_ptr = error; 667 m_write_sp.reset(socket); 668 m_read_sp = m_write_sp; 669 if (error.Fail()) { 670 return eConnectionStatusError; 671 } 672 m_uri.assign(socket_name); 673 return eConnectionStatusSuccess; 674 } 675 676 ConnectionStatus 677 ConnectionFileDescriptor::NamedSocketConnect(llvm::StringRef socket_name, 678 Error *error_ptr) { 679 Socket *socket = nullptr; 680 Error error = 681 Socket::UnixDomainConnect(socket_name, m_child_processes_inherit, socket); 682 if (error_ptr) 683 *error_ptr = error; 684 m_write_sp.reset(socket); 685 m_read_sp = m_write_sp; 686 if (error.Fail()) { 687 return eConnectionStatusError; 688 } 689 m_uri.assign(socket_name); 690 return eConnectionStatusSuccess; 691 } 692 693 lldb::ConnectionStatus 694 ConnectionFileDescriptor::UnixAbstractSocketConnect(llvm::StringRef socket_name, 695 Error *error_ptr) { 696 Socket *socket = nullptr; 697 Error error = Socket::UnixAbstractConnect(socket_name, 698 m_child_processes_inherit, socket); 699 if (error_ptr) 700 *error_ptr = error; 701 m_write_sp.reset(socket); 702 m_read_sp = m_write_sp; 703 if (error.Fail()) { 704 return eConnectionStatusError; 705 } 706 m_uri.assign(socket_name); 707 return eConnectionStatusSuccess; 708 } 709 710 ConnectionStatus 711 ConnectionFileDescriptor::SocketListenAndAccept(llvm::StringRef s, 712 Error *error_ptr) { 713 m_port_predicate.SetValue(0, eBroadcastNever); 714 715 Socket *socket = nullptr; 716 m_waiting_for_accept = true; 717 Error error = Socket::TcpListen(s, m_child_processes_inherit, socket, 718 &m_port_predicate); 719 if (error_ptr) 720 *error_ptr = error; 721 if (error.Fail()) 722 return eConnectionStatusError; 723 724 std::unique_ptr<Socket> listening_socket_up; 725 726 listening_socket_up.reset(socket); 727 socket = nullptr; 728 error = listening_socket_up->Accept(s, m_child_processes_inherit, socket); 729 listening_socket_up.reset(); 730 if (error_ptr) 731 *error_ptr = error; 732 if (error.Fail()) 733 return eConnectionStatusError; 734 735 InitializeSocket(socket); 736 return eConnectionStatusSuccess; 737 } 738 739 ConnectionStatus ConnectionFileDescriptor::ConnectTCP(llvm::StringRef s, 740 Error *error_ptr) { 741 Socket *socket = nullptr; 742 Error error = Socket::TcpConnect(s, m_child_processes_inherit, socket); 743 if (error_ptr) 744 *error_ptr = error; 745 m_write_sp.reset(socket); 746 m_read_sp = m_write_sp; 747 if (error.Fail()) { 748 return eConnectionStatusError; 749 } 750 m_uri.assign(s); 751 return eConnectionStatusSuccess; 752 } 753 754 ConnectionStatus ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s, 755 Error *error_ptr) { 756 Socket *send_socket = nullptr; 757 Socket *recv_socket = nullptr; 758 Error error = Socket::UdpConnect(s, m_child_processes_inherit, send_socket, 759 recv_socket); 760 if (error_ptr) 761 *error_ptr = error; 762 m_write_sp.reset(send_socket); 763 m_read_sp.reset(recv_socket); 764 if (error.Fail()) { 765 return eConnectionStatusError; 766 } 767 m_uri.assign(s); 768 return eConnectionStatusSuccess; 769 } 770 771 uint16_t ConnectionFileDescriptor::GetListeningPort(uint32_t timeout_sec) { 772 uint16_t bound_port = 0; 773 if (timeout_sec == UINT32_MAX) 774 m_port_predicate.WaitForValueNotEqualTo(0, bound_port); 775 else 776 m_port_predicate.WaitForValueNotEqualTo(0, bound_port, 777 std::chrono::seconds(timeout_sec)); 778 return bound_port; 779 } 780 781 bool ConnectionFileDescriptor::GetChildProcessesInherit() const { 782 return m_child_processes_inherit; 783 } 784 785 void ConnectionFileDescriptor::SetChildProcessesInherit( 786 bool child_processes_inherit) { 787 m_child_processes_inherit = child_processes_inherit; 788 } 789 790 void ConnectionFileDescriptor::InitializeSocket(Socket *socket) { 791 assert(socket->GetSocketProtocol() == Socket::ProtocolTcp); 792 TCPSocket *tcp_socket = static_cast<TCPSocket *>(socket); 793 794 m_write_sp.reset(socket); 795 m_read_sp = m_write_sp; 796 StreamString strm; 797 strm.Printf("connect://%s:%u", tcp_socket->GetRemoteIPAddress().c_str(), 798 tcp_socket->GetRemotePortNumber()); 799 m_uri = strm.GetString(); 800 } 801