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