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(), 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(), 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)", 108 static_cast<void *>(this), fd, owns_fd); 109 OpenCommandPipe(); 110 } 111 112 ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket) 113 : Connection(), 114 m_pipe(), 115 m_mutex(), 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 std::lock_guard<std::recursive_mutex> guard(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 std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock); 378 if (!locker.try_lock()) 379 { 380 if (m_pipe.CanWrite()) 381 { 382 size_t bytes_written = 0; 383 Error result = m_pipe.Write("q", 1, bytes_written); 384 if (log) 385 log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, sent 'q' to %d, error = '%s'.", 386 static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(), result.AsCString()); 387 } 388 else if (log) 389 { 390 log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.", 391 static_cast<void *>(this)); 392 } 393 locker.lock(); 394 } 395 396 Error error = m_read_sp->Close(); 397 Error error2 = m_write_sp->Close(); 398 if (error.Fail() || error2.Fail()) 399 status = eConnectionStatusError; 400 if (error_ptr) 401 *error_ptr = error.Fail() ? error : error2; 402 403 // Close any pipes we were using for async interrupts 404 m_pipe.Close(); 405 406 m_uri.clear(); 407 m_shutting_down = false; 408 return status; 409 } 410 411 size_t 412 ConnectionFileDescriptor::Read(void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr) 413 { 414 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 415 416 std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock); 417 if (!locker.try_lock()) 418 { 419 if (log) 420 log->Printf("%p ConnectionFileDescriptor::Read () failed to get the connection lock.", static_cast<void *>(this)); 421 if (error_ptr) 422 error_ptr->SetErrorString("failed to get the connection lock for read."); 423 424 status = eConnectionStatusTimedOut; 425 return 0; 426 } 427 428 if (m_shutting_down) 429 { 430 status = eConnectionStatusError; 431 return 0; 432 } 433 434 status = BytesAvailable(timeout_usec, error_ptr); 435 if (status != eConnectionStatusSuccess) 436 return 0; 437 438 Error error; 439 size_t bytes_read = dst_len; 440 error = m_read_sp->Read(dst, bytes_read); 441 442 if (log) 443 { 444 log->Printf("%p ConnectionFileDescriptor::Read() fd = %" PRIu64 ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s", 445 static_cast<void *>(this), static_cast<uint64_t>(m_read_sp->GetWaitableHandle()), static_cast<void *>(dst), 446 static_cast<uint64_t>(dst_len), static_cast<uint64_t>(bytes_read), error.AsCString()); 447 } 448 449 if (bytes_read == 0) 450 { 451 error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers. 452 status = eConnectionStatusEndOfFile; 453 } 454 455 if (error_ptr) 456 *error_ptr = error; 457 458 if (error.Fail()) 459 { 460 uint32_t error_value = error.GetError(); 461 switch (error_value) 462 { 463 case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read. 464 if (m_read_sp->GetFdType() == IOObject::eFDTypeSocket) 465 status = eConnectionStatusTimedOut; 466 else 467 status = eConnectionStatusSuccess; 468 return 0; 469 470 case EFAULT: // Buf points outside the allocated address space. 471 case EINTR: // A read from a slow device was interrupted before any data arrived by the delivery of a signal. 472 case EINVAL: // The pointer associated with fildes was negative. 473 case EIO: // An I/O error occurred while reading from the file system. 474 // The process group is orphaned. 475 // The file is a regular file, nbyte is greater than 0, 476 // the starting position is before the end-of-file, and 477 // the starting position is greater than or equal to the 478 // offset maximum established for the open file 479 // descriptor associated with fildes. 480 case EISDIR: // An attempt is made to read a directory. 481 case ENOBUFS: // An attempt to allocate a memory buffer fails. 482 case ENOMEM: // Insufficient memory is available. 483 status = eConnectionStatusError; 484 break; // Break to close.... 485 486 case ENOENT: // no such file or directory 487 case EBADF: // fildes is not a valid file or socket descriptor open for reading. 488 case ENXIO: // An action is requested of a device that does not exist.. 489 // A requested action cannot be performed by the device. 490 case ECONNRESET: // The connection is closed by the peer during a read attempt on a socket. 491 case ENOTCONN: // A read is attempted on an unconnected socket. 492 status = eConnectionStatusLostConnection; 493 break; // Break to close.... 494 495 case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket. 496 status = eConnectionStatusTimedOut; 497 return 0; 498 499 default: 500 if (log) 501 log->Printf("%p ConnectionFileDescriptor::Read (), unexpected error: %s", static_cast<void *>(this), 502 strerror(error_value)); 503 status = eConnectionStatusError; 504 break; // Break to close.... 505 } 506 507 return 0; 508 } 509 return bytes_read; 510 } 511 512 size_t 513 ConnectionFileDescriptor::Write(const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) 514 { 515 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 516 if (log) 517 log->Printf("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", static_cast<void *>(this), 518 static_cast<const void *>(src), static_cast<uint64_t>(src_len)); 519 520 if (!IsConnected()) 521 { 522 if (error_ptr) 523 error_ptr->SetErrorString("not connected"); 524 status = eConnectionStatusNoConnection; 525 return 0; 526 } 527 528 Error error; 529 530 size_t bytes_sent = src_len; 531 error = m_write_sp->Write(src, bytes_sent); 532 533 if (log) 534 { 535 log->Printf("%p ConnectionFileDescriptor::Write(fd = %" PRIu64 ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)", 536 static_cast<void *>(this), static_cast<uint64_t>(m_write_sp->GetWaitableHandle()), static_cast<const void *>(src), 537 static_cast<uint64_t>(src_len), static_cast<uint64_t>(bytes_sent), error.AsCString()); 538 } 539 540 if (error_ptr) 541 *error_ptr = error; 542 543 if (error.Fail()) 544 { 545 switch (error.GetError()) 546 { 547 case EAGAIN: 548 case EINTR: 549 status = eConnectionStatusSuccess; 550 return 0; 551 552 case ECONNRESET: // The connection is closed by the peer during a read attempt on a socket. 553 case ENOTCONN: // A read is attempted on an unconnected socket. 554 status = eConnectionStatusLostConnection; 555 break; // Break to close.... 556 557 default: 558 status = eConnectionStatusError; 559 break; // Break to close.... 560 } 561 562 return 0; 563 } 564 565 status = eConnectionStatusSuccess; 566 return bytes_sent; 567 } 568 569 std::string 570 ConnectionFileDescriptor::GetURI() 571 { 572 return m_uri; 573 } 574 575 // This ConnectionFileDescriptor::BytesAvailable() uses select(). 576 // 577 // PROS: 578 // - select is consistent across most unix platforms 579 // - The Apple specific version allows for unlimited fds in the fd_sets by 580 // setting the _DARWIN_UNLIMITED_SELECT define prior to including the 581 // required header files. 582 // CONS: 583 // - on non-Apple platforms, only supports file descriptors up to FD_SETSIZE. 584 // This implementation will assert if it runs into that hard limit to let 585 // users know that another ConnectionFileDescriptor::BytesAvailable() should 586 // be used or a new version of ConnectionFileDescriptor::BytesAvailable() 587 // should be written for the system that is running into the limitations. 588 589 #if defined(__APPLE__) 590 #define FD_SET_DATA(fds) fds.data() 591 #else 592 #define FD_SET_DATA(fds) &fds 593 #endif 594 595 ConnectionStatus 596 ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr) 597 { 598 // Don't need to take the mutex here separately since we are only called from Read. If we 599 // ever get used more generally we will need to lock here as well. 600 601 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION)); 602 if (log) 603 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", static_cast<void *>(this), timeout_usec); 604 605 struct timeval *tv_ptr; 606 struct timeval tv; 607 if (timeout_usec == UINT32_MAX) 608 { 609 // Inifinite wait... 610 tv_ptr = nullptr; 611 } 612 else 613 { 614 TimeValue time_value; 615 time_value.OffsetWithMicroSeconds(timeout_usec); 616 tv.tv_sec = time_value.seconds(); 617 tv.tv_usec = time_value.microseconds(); 618 tv_ptr = &tv; 619 } 620 621 // Make a copy of the file descriptors to make sure we don't 622 // have another thread change these values out from under us 623 // and cause problems in the loop below where like in FS_SET() 624 const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle(); 625 const int pipe_fd = m_pipe.GetReadFileDescriptor(); 626 627 if (handle != IOObject::kInvalidHandleValue) 628 { 629 #if defined(_MSC_VER) 630 // select() won't accept pipes on Windows. The entire Windows codepath needs to be 631 // converted over to using WaitForMultipleObjects and event HANDLEs, but for now at least 632 // this will allow ::select() to not return an error. 633 const bool have_pipe_fd = false; 634 #else 635 const bool have_pipe_fd = pipe_fd >= 0; 636 #if !defined(__APPLE__) 637 assert(handle < FD_SETSIZE); 638 if (have_pipe_fd) 639 assert(pipe_fd < FD_SETSIZE); 640 #endif 641 #endif 642 while (handle == m_read_sp->GetWaitableHandle()) 643 { 644 const int nfds = std::max<int>(handle, pipe_fd) + 1; 645 #if defined(__APPLE__) 646 llvm::SmallVector<fd_set, 1> read_fds; 647 read_fds.resize((nfds / FD_SETSIZE) + 1); 648 for (size_t i = 0; i < read_fds.size(); ++i) 649 FD_ZERO(&read_fds[i]); 650 // FD_SET doesn't bounds check, it just happily walks off the end 651 // but we have taken care of making the extra storage with our 652 // SmallVector of fd_set objects 653 #else 654 fd_set read_fds; 655 FD_ZERO(&read_fds); 656 #endif 657 FD_SET(handle, FD_SET_DATA(read_fds)); 658 if (have_pipe_fd) 659 FD_SET(pipe_fd, FD_SET_DATA(read_fds)); 660 661 Error error; 662 663 if (log) 664 { 665 if (have_pipe_fd) 666 log->Printf( 667 "%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...", 668 static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr)); 669 else 670 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...", 671 static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr)); 672 } 673 674 const int num_set_fds = ::select(nfds, FD_SET_DATA(read_fds), NULL, NULL, tv_ptr); 675 if (num_set_fds < 0) 676 error.SetErrorToErrno(); 677 else 678 error.Clear(); 679 680 if (log) 681 { 682 if (have_pipe_fd) 683 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) " 684 "=> %d, error = %s", 685 static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr), num_set_fds, 686 error.AsCString()); 687 else 688 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => " 689 "%d, error = %s", 690 static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr), num_set_fds, error.AsCString()); 691 } 692 693 if (error_ptr) 694 *error_ptr = error; 695 696 if (error.Fail()) 697 { 698 switch (error.GetError()) 699 { 700 case EBADF: // One of the descriptor sets specified an invalid descriptor. 701 return eConnectionStatusLostConnection; 702 703 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. 704 default: // Other unknown error 705 return eConnectionStatusError; 706 707 case EAGAIN: // The kernel was (perhaps temporarily) unable to 708 // allocate the requested number of file descriptors, 709 // or we have non-blocking IO 710 case EINTR: // A signal was delivered before the time limit 711 // expired and before any of the selected events 712 // occurred. 713 break; // Lets keep reading to until we timeout 714 } 715 } 716 else if (num_set_fds == 0) 717 { 718 return eConnectionStatusTimedOut; 719 } 720 else if (num_set_fds > 0) 721 { 722 if (FD_ISSET(handle, FD_SET_DATA(read_fds))) 723 return eConnectionStatusSuccess; 724 if (have_pipe_fd && FD_ISSET(pipe_fd, FD_SET_DATA(read_fds))) 725 { 726 // There is an interrupt or exit command in the command pipe 727 // Read the data from that pipe: 728 char buffer[1]; 729 730 ssize_t bytes_read; 731 732 do 733 { 734 bytes_read = ::read(pipe_fd, buffer, sizeof(buffer)); 735 } while (bytes_read < 0 && errno == EINTR); 736 737 switch (buffer[0]) 738 { 739 case 'q': 740 if (log) 741 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() " 742 "got data: %c from the command channel.", 743 static_cast<void *>(this), buffer[0]); 744 return eConnectionStatusEndOfFile; 745 case 'i': 746 // Interrupt the current read 747 return eConnectionStatusInterrupted; 748 } 749 } 750 } 751 } 752 } 753 754 if (error_ptr) 755 error_ptr->SetErrorString("not connected"); 756 return eConnectionStatusLostConnection; 757 } 758 759 ConnectionStatus 760 ConnectionFileDescriptor::NamedSocketAccept(const char *socket_name, Error *error_ptr) 761 { 762 Socket *socket = nullptr; 763 Error error = Socket::UnixDomainAccept(socket_name, m_child_processes_inherit, socket); 764 if (error_ptr) 765 *error_ptr = error; 766 m_write_sp.reset(socket); 767 m_read_sp = m_write_sp; 768 if (error.Fail()) 769 { 770 return eConnectionStatusError; 771 } 772 m_uri.assign(socket_name); 773 return eConnectionStatusSuccess; 774 } 775 776 ConnectionStatus 777 ConnectionFileDescriptor::NamedSocketConnect(const char *socket_name, Error *error_ptr) 778 { 779 Socket *socket = nullptr; 780 Error error = Socket::UnixDomainConnect(socket_name, m_child_processes_inherit, socket); 781 if (error_ptr) 782 *error_ptr = error; 783 m_write_sp.reset(socket); 784 m_read_sp = m_write_sp; 785 if (error.Fail()) 786 { 787 return eConnectionStatusError; 788 } 789 m_uri.assign(socket_name); 790 return eConnectionStatusSuccess; 791 } 792 793 lldb::ConnectionStatus 794 ConnectionFileDescriptor::UnixAbstractSocketConnect(const char *socket_name, Error *error_ptr) 795 { 796 Socket *socket = nullptr; 797 Error error = Socket::UnixAbstractConnect(socket_name, m_child_processes_inherit, socket); 798 if (error_ptr) 799 *error_ptr = error; 800 m_write_sp.reset(socket); 801 m_read_sp = m_write_sp; 802 if (error.Fail()) 803 { 804 return eConnectionStatusError; 805 } 806 m_uri.assign(socket_name); 807 return eConnectionStatusSuccess; 808 } 809 810 ConnectionStatus 811 ConnectionFileDescriptor::SocketListenAndAccept(const char *s, Error *error_ptr) 812 { 813 m_port_predicate.SetValue(0, eBroadcastNever); 814 815 Socket *socket = nullptr; 816 m_waiting_for_accept = true; 817 Error error = Socket::TcpListen(s, m_child_processes_inherit, socket, &m_port_predicate); 818 if (error_ptr) 819 *error_ptr = error; 820 if (error.Fail()) 821 return eConnectionStatusError; 822 823 std::unique_ptr<Socket> listening_socket_up; 824 825 listening_socket_up.reset(socket); 826 socket = nullptr; 827 error = listening_socket_up->Accept(s, m_child_processes_inherit, socket); 828 listening_socket_up.reset(); 829 if (error_ptr) 830 *error_ptr = error; 831 if (error.Fail()) 832 return eConnectionStatusError; 833 834 InitializeSocket(socket); 835 return eConnectionStatusSuccess; 836 } 837 838 ConnectionStatus 839 ConnectionFileDescriptor::ConnectTCP(const char *s, Error *error_ptr) 840 { 841 Socket *socket = nullptr; 842 Error error = Socket::TcpConnect(s, m_child_processes_inherit, socket); 843 if (error_ptr) 844 *error_ptr = error; 845 m_write_sp.reset(socket); 846 m_read_sp = m_write_sp; 847 if (error.Fail()) 848 { 849 return eConnectionStatusError; 850 } 851 m_uri.assign(s); 852 return eConnectionStatusSuccess; 853 } 854 855 ConnectionStatus 856 ConnectionFileDescriptor::ConnectUDP(const char *s, Error *error_ptr) 857 { 858 Socket *send_socket = nullptr; 859 Socket *recv_socket = nullptr; 860 Error error = Socket::UdpConnect(s, m_child_processes_inherit, send_socket, recv_socket); 861 if (error_ptr) 862 *error_ptr = error; 863 m_write_sp.reset(send_socket); 864 m_read_sp.reset(recv_socket); 865 if (error.Fail()) 866 { 867 return eConnectionStatusError; 868 } 869 m_uri.assign(s); 870 return eConnectionStatusSuccess; 871 } 872 873 uint16_t 874 ConnectionFileDescriptor::GetListeningPort(uint32_t timeout_sec) 875 { 876 uint16_t bound_port = 0; 877 if (timeout_sec == UINT32_MAX) 878 m_port_predicate.WaitForValueNotEqualTo(0, bound_port); 879 else 880 { 881 TimeValue timeout = TimeValue::Now(); 882 timeout.OffsetWithSeconds(timeout_sec); 883 m_port_predicate.WaitForValueNotEqualTo(0, bound_port, &timeout); 884 } 885 return bound_port; 886 } 887 888 bool 889 ConnectionFileDescriptor::GetChildProcessesInherit() const 890 { 891 return m_child_processes_inherit; 892 } 893 894 void 895 ConnectionFileDescriptor::SetChildProcessesInherit(bool child_processes_inherit) 896 { 897 m_child_processes_inherit = child_processes_inherit; 898 } 899 900 void 901 ConnectionFileDescriptor::InitializeSocket(Socket* socket) 902 { 903 assert(socket->GetSocketProtocol() == Socket::ProtocolTcp); 904 TCPSocket* tcp_socket = static_cast<TCPSocket*>(socket); 905 906 m_write_sp.reset(socket); 907 m_read_sp = m_write_sp; 908 StreamString strm; 909 strm.Printf("connect://%s:%u",tcp_socket->GetRemoteIPAddress().c_str(), tcp_socket->GetRemotePortNumber()); 910 m_uri.swap(strm.GetString()); 911 } 912