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