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