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