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