ConnectionFileDescriptor.cpp revision f88bf3d150de0d7818d0cc65d104d58521c60699
1//===-- ConnectionFileDescriptor.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/Core/ConnectionFileDescriptor.h" 18 19// C Includes 20#include <errno.h> 21#include <fcntl.h> 22#include <arpa/inet.h> 23#include <netdb.h> 24#include <netinet/in.h> 25#include <netinet/tcp.h> 26#include <sys/socket.h> 27#include <sys/un.h> 28#include <sys/types.h> 29#include <string.h> 30#include <stdlib.h> 31#include <unistd.h> 32 33// C++ Includes 34// Other libraries and framework includes 35#if defined(__APPLE__) 36#include "llvm/ADT/SmallVector.h" 37#endif 38// Project includes 39#include "lldb/lldb-private-log.h" 40#include "lldb/Interpreter/Args.h" 41#include "lldb/Core/Communication.h" 42#include "lldb/Core/Log.h" 43#include "lldb/Core/RegularExpression.h" 44#include "lldb/Core/Timer.h" 45 46using namespace lldb; 47using namespace lldb_private; 48 49static bool 50DecodeHostAndPort (const char *host_and_port, 51 std::string &host_str, 52 std::string &port_str, 53 int32_t& port, 54 Error *error_ptr) 55{ 56 RegularExpression regex ("([^:]+):([0-9]+)"); 57 if (regex.Execute (host_and_port, 2)) 58 { 59 if (regex.GetMatchAtIndex (host_and_port, 1, host_str) && 60 regex.GetMatchAtIndex (host_and_port, 2, port_str)) 61 { 62 port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN); 63 if (port != INT32_MIN) 64 { 65 if (error_ptr) 66 error_ptr->Clear(); 67 return true; 68 } 69 } 70 } 71 host_str.clear(); 72 port_str.clear(); 73 port = INT32_MIN; 74 if (error_ptr) 75 error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port); 76 return false; 77} 78 79ConnectionFileDescriptor::ConnectionFileDescriptor () : 80 Connection(), 81 m_fd_send (-1), 82 m_fd_recv (-1), 83 m_fd_send_type (eFDTypeFile), 84 m_fd_recv_type (eFDTypeFile), 85 m_udp_send_sockaddr (), 86 m_should_close_fd (false), 87 m_socket_timeout_usec(0), 88 m_pipe_read(-1), 89 m_pipe_write(-1), 90 m_mutex (Mutex::eMutexTypeRecursive), 91 m_shutting_down (false) 92{ 93 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); 94 if (log) 95 log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", this); 96} 97 98ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) : 99 Connection(), 100 m_fd_send (fd), 101 m_fd_recv (fd), 102 m_fd_send_type (eFDTypeFile), 103 m_fd_recv_type (eFDTypeFile), 104 m_udp_send_sockaddr (), 105 m_should_close_fd (owns_fd), 106 m_socket_timeout_usec(0), 107 m_pipe_read(-1), 108 m_pipe_write(-1), 109 m_mutex (Mutex::eMutexTypeRecursive), 110 m_shutting_down (false) 111{ 112 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); 113 if (log) 114 log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", this, fd, owns_fd); 115 OpenCommandPipe (); 116} 117 118 119ConnectionFileDescriptor::~ConnectionFileDescriptor () 120{ 121 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); 122 if (log) 123 log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", this); 124 Disconnect (NULL); 125 CloseCommandPipe (); 126} 127 128void 129ConnectionFileDescriptor::OpenCommandPipe () 130{ 131 CloseCommandPipe(); 132 133 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 134 // Make the command file descriptor here: 135 int filedes[2]; 136 int result = pipe (filedes); 137 if (result != 0) 138 { 139 if (log) 140 log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor () - could not make pipe: %s", 141 this, 142 strerror(errno)); 143 } 144 else 145 { 146 m_pipe_read = filedes[0]; 147 m_pipe_write = filedes[1]; 148 } 149} 150 151void 152ConnectionFileDescriptor::CloseCommandPipe () 153{ 154 if (m_pipe_read != -1) 155 { 156 close (m_pipe_read); 157 m_pipe_read = -1; 158 } 159 160 if (m_pipe_write != -1) 161 { 162 close (m_pipe_write); 163 m_pipe_write = -1; 164 } 165} 166 167bool 168ConnectionFileDescriptor::IsConnected () const 169{ 170 return m_fd_send >= 0 || m_fd_recv >= 0; 171} 172 173ConnectionStatus 174ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) 175{ 176 Mutex::Locker locker (m_mutex); 177 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 178 if (log) 179 log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", this, s); 180 181 OpenCommandPipe(); 182 183 if (s && s[0]) 184 { 185 char *end = NULL; 186 if (strstr(s, "listen://")) 187 { 188 // listen://HOST:PORT 189 unsigned long listen_port = ::strtoul(s + strlen("listen://"), &end, 0); 190 return SocketListen (listen_port, error_ptr); 191 } 192 else if (strstr(s, "unix-accept://")) 193 { 194 // unix://SOCKNAME 195 return NamedSocketAccept (s + strlen("unix-accept://"), error_ptr); 196 } 197 else if (strstr(s, "connect://")) 198 { 199 return ConnectTCP (s + strlen("connect://"), error_ptr); 200 } 201 else if (strstr(s, "tcp-connect://")) 202 { 203 return ConnectTCP (s + strlen("tcp-connect://"), error_ptr); 204 } 205 else if (strstr(s, "udp://")) 206 { 207 return ConnectUDP (s + strlen("udp://"), error_ptr); 208 } 209 else if (strstr(s, "fd://")) 210 { 211 // Just passing a native file descriptor within this current process 212 // that is already opened (possibly from a service or other source). 213 s += strlen ("fd://"); 214 bool success = false; 215 m_fd_send = m_fd_recv = Args::StringToSInt32 (s, -1, 0, &success); 216 217 if (success) 218 { 219 // We have what looks to be a valid file descriptor, but we 220 // should make sure it is. We currently are doing this by trying to 221 // get the flags from the file descriptor and making sure it 222 // isn't a bad fd. 223 errno = 0; 224 int flags = ::fcntl (m_fd_send, F_GETFL, 0); 225 if (flags == -1 || errno == EBADF) 226 { 227 if (error_ptr) 228 error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s); 229 m_fd_send = m_fd_recv = -1; 230 return eConnectionStatusError; 231 } 232 else 233 { 234 // Try and get a socket option from this file descriptor to 235 // see if this is a socket and set m_is_socket accordingly. 236 int resuse; 237 bool is_socket = GetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, resuse) == 0; 238 if (is_socket) 239 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 240 // Don't take ownership of a file descriptor that gets passed 241 // to us since someone else opened the file descriptor and 242 // handed it to us. 243 // TODO: Since are using a URL to open connection we should 244 // eventually parse options using the web standard where we 245 // have "fd://123?opt1=value;opt2=value" and we can have an 246 // option be "owns=1" or "owns=0" or something like this to 247 // allow us to specify this. For now, we assume we must 248 // assume we don't own it. 249 m_should_close_fd = false; 250 return eConnectionStatusSuccess; 251 } 252 } 253 254 if (error_ptr) 255 error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s); 256 m_fd_send = m_fd_recv = -1; 257 return eConnectionStatusError; 258 } 259 else if (strstr(s, "file://")) 260 { 261 // file:///PATH 262 const char *path = s + strlen("file://"); 263 do 264 { 265 m_fd_send = m_fd_recv = ::open (path, O_RDWR); 266 } while (m_fd_send == -1 && errno == EINTR); 267 if (m_fd_send == -1) 268 { 269 if (error_ptr) 270 error_ptr->SetErrorToErrno(); 271 return eConnectionStatusError; 272 } 273 274 int flags = ::fcntl (m_fd_send, F_GETFL, 0); 275 if (flags >= 0) 276 { 277 if ((flags & O_NONBLOCK) == 0) 278 { 279 flags |= O_NONBLOCK; 280 ::fcntl (m_fd_send, F_SETFL, flags); 281 } 282 } 283 m_should_close_fd = true; 284 return eConnectionStatusSuccess; 285 } 286 if (error_ptr) 287 error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s); 288 return eConnectionStatusError; 289 } 290 if (error_ptr) 291 error_ptr->SetErrorString("invalid connect arguments"); 292 return eConnectionStatusError; 293} 294 295ConnectionStatus 296ConnectionFileDescriptor::Disconnect (Error *error_ptr) 297{ 298 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 299 if (log) 300 log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this); 301 302 ConnectionStatus status = eConnectionStatusSuccess; 303 304 if (m_fd_send < 0 && m_fd_recv < 0) 305 { 306 if (log) 307 log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", this); 308 return eConnectionStatusSuccess; 309 } 310 311 // Try to get the ConnectionFileDescriptor's mutex. If we fail, that is quite likely 312 // because somebody is doing a blocking read on our file descriptor. If that's the case, 313 // then send the "q" char to the command file channel so the read will wake up and the connection 314 // will then know to shut down. 315 316 m_shutting_down = true; 317 318 Mutex::Locker locker; 319 bool got_lock= locker.TryLock (m_mutex); 320 321 if (!got_lock) 322 { 323 if (m_pipe_write != -1 ) 324 { 325 write (m_pipe_write, "q", 1); 326 close (m_pipe_write); 327 m_pipe_write = -1; 328 } 329 locker.Lock (m_mutex); 330 } 331 332 if (m_should_close_fd == true) 333 { 334 if (m_fd_send == m_fd_recv) 335 { 336 status = Close (m_fd_send, error_ptr); 337 } 338 else 339 { 340 // File descriptors are the different, close both if needed 341 if (m_fd_send >= 0) 342 status = Close (m_fd_send, error_ptr); 343 if (m_fd_recv >= 0) 344 { 345 ConnectionStatus recv_status = Close (m_fd_recv, error_ptr); 346 if (status == eConnectionStatusSuccess) 347 status = recv_status; 348 } 349 } 350 } 351 352 // Now set all our descriptors to invalid values. 353 354 m_fd_send = m_fd_recv = -1; 355 356 if (status != eConnectionStatusSuccess) 357 { 358 359 return status; 360 } 361 362 m_shutting_down = false; 363 return eConnectionStatusSuccess; 364} 365 366size_t 367ConnectionFileDescriptor::Read (void *dst, 368 size_t dst_len, 369 uint32_t timeout_usec, 370 ConnectionStatus &status, 371 Error *error_ptr) 372{ 373 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 374 if (log) 375 log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ")...", 376 this, m_fd_recv, dst, (uint64_t)dst_len); 377 378 Mutex::Locker locker; 379 bool got_lock = locker.TryLock (m_mutex); 380 if (!got_lock) 381 { 382 if (log) 383 log->Printf ("%p ConnectionFileDescriptor::Read () failed to get the connection lock.", 384 this); 385 if (error_ptr) 386 error_ptr->SetErrorString ("failed to get the connection lock for read."); 387 388 status = eConnectionStatusTimedOut; 389 return 0; 390 } 391 else if (m_shutting_down) 392 return eConnectionStatusError; 393 394 ssize_t bytes_read = 0; 395 396 status = BytesAvailable (timeout_usec, error_ptr); 397 if (status == eConnectionStatusSuccess) 398 { 399 do 400 { 401 bytes_read = ::read (m_fd_recv, dst, dst_len); 402 } while (bytes_read < 0 && errno == EINTR); 403 } 404 405 if (status != eConnectionStatusSuccess) 406 return 0; 407 408 Error error; 409 if (bytes_read == 0) 410 { 411 error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers. 412 status = eConnectionStatusEndOfFile; 413 } 414 else if (bytes_read < 0) 415 { 416 error.SetErrorToErrno(); 417 } 418 else 419 { 420 error.Clear(); 421 } 422 423 if (log) 424 log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ") => %" PRIi64 ", error = %s", 425 this, 426 m_fd_recv, 427 dst, 428 (uint64_t)dst_len, 429 (int64_t)bytes_read, 430 error.AsCString()); 431 432 if (error_ptr) 433 *error_ptr = error; 434 435 if (error.Fail()) 436 { 437 uint32_t error_value = error.GetError(); 438 switch (error_value) 439 { 440 case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read. 441 if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP) 442 status = eConnectionStatusTimedOut; 443 else 444 status = eConnectionStatusSuccess; 445 return 0; 446 447 case EFAULT: // Buf points outside the allocated address space. 448 case EINTR: // A read from a slow device was interrupted before any data arrived by the delivery of a signal. 449 case EINVAL: // The pointer associated with fildes was negative. 450 case EIO: // An I/O error occurred while reading from the file system. 451 // The process group is orphaned. 452 // The file is a regular file, nbyte is greater than 0, 453 // the starting position is before the end-of-file, and 454 // the starting position is greater than or equal to the 455 // offset maximum established for the open file 456 // descriptor associated with fildes. 457 case EISDIR: // An attempt is made to read a directory. 458 case ENOBUFS: // An attempt to allocate a memory buffer fails. 459 case ENOMEM: // Insufficient memory is available. 460 status = eConnectionStatusError; 461 break; // Break to close.... 462 463 case ENOENT: // no such file or directory 464 case EBADF: // fildes is not a valid file or socket descriptor open for reading. 465 case ENXIO: // An action is requested of a device that does not exist.. 466 // A requested action cannot be performed by the device. 467 case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket. 468 case ENOTCONN: // A read is attempted on an unconnected socket. 469 status = eConnectionStatusLostConnection; 470 break; // Break to close.... 471 472 case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket. 473 status = eConnectionStatusTimedOut; 474 return 0; 475 } 476 477 return 0; 478 } 479 return bytes_read; 480} 481 482size_t 483ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) 484{ 485 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 486 if (log) 487 log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", this, src, (uint64_t)src_len); 488 489 if (!IsConnected ()) 490 { 491 if (error_ptr) 492 error_ptr->SetErrorString("not connected"); 493 status = eConnectionStatusNoConnection; 494 return 0; 495 } 496 497 498 Error error; 499 500 ssize_t bytes_sent = 0; 501 502 switch (m_fd_send_type) 503 { 504 case eFDTypeFile: // Other FD requireing read/write 505 do 506 { 507 bytes_sent = ::write (m_fd_send, src, src_len); 508 } while (bytes_sent < 0 && errno == EINTR); 509 break; 510 511 case eFDTypeSocket: // Socket requiring send/recv 512 do 513 { 514 bytes_sent = ::send (m_fd_send, src, src_len, 0); 515 } while (bytes_sent < 0 && errno == EINTR); 516 break; 517 518 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom 519 assert (m_udp_send_sockaddr.GetFamily() != 0); 520 do 521 { 522 bytes_sent = ::sendto (m_fd_send, 523 src, 524 src_len, 525 0, 526 m_udp_send_sockaddr, 527 m_udp_send_sockaddr.GetLength()); 528 } while (bytes_sent < 0 && errno == EINTR); 529 break; 530 } 531 532 if (bytes_sent < 0) 533 error.SetErrorToErrno (); 534 else 535 error.Clear (); 536 537 if (log) 538 { 539 switch (m_fd_send_type) 540 { 541 case eFDTypeFile: // Other FD requireing read/write 542 log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %" PRIu64 ") => %" PRIi64 " (error = %s)", 543 this, 544 m_fd_send, 545 src, 546 (uint64_t)src_len, 547 (int64_t)bytes_sent, 548 error.AsCString()); 549 break; 550 551 case eFDTypeSocket: // Socket requiring send/recv 552 log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)", 553 this, 554 m_fd_send, 555 src, 556 (uint64_t)src_len, 557 (int64_t)bytes_sent, 558 error.AsCString()); 559 break; 560 561 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom 562 log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)", 563 this, 564 m_fd_send, 565 src, 566 (uint64_t)src_len, 567 (int64_t)bytes_sent, 568 error.AsCString()); 569 break; 570 } 571 } 572 573 if (error_ptr) 574 *error_ptr = error; 575 576 if (error.Fail()) 577 { 578 switch (error.GetError()) 579 { 580 case EAGAIN: 581 case EINTR: 582 status = eConnectionStatusSuccess; 583 return 0; 584 585 case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket. 586 case ENOTCONN: // A read is attempted on an unconnected socket. 587 status = eConnectionStatusLostConnection; 588 break; // Break to close.... 589 590 default: 591 status = eConnectionStatusError; 592 break; // Break to close.... 593 } 594 595 return 0; 596 } 597 598 status = eConnectionStatusSuccess; 599 return bytes_sent; 600} 601 602 603 604#if defined(__APPLE__) 605 606// This ConnectionFileDescriptor::BytesAvailable() uses select(). 607// 608// PROS: 609// - select is consistent across most unix platforms 610// - this Apple specific version allows for unlimited fds in the fd_sets by 611// setting the _DARWIN_UNLIMITED_SELECT define prior to including the 612// required header files. 613 614// CONS: 615// - Darwin only 616 617ConnectionStatus 618ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) 619{ 620 // Don't need to take the mutex here separately since we are only called from Read. If we 621 // ever get used more generally we will need to lock here as well. 622 623 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 624 if (log) 625 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec); 626 struct timeval *tv_ptr; 627 struct timeval tv; 628 if (timeout_usec == UINT32_MAX) 629 { 630 // Infinite wait... 631 tv_ptr = NULL; 632 } 633 else 634 { 635 TimeValue time_value; 636 time_value.OffsetWithMicroSeconds (timeout_usec); 637 tv = time_value.GetAsTimeVal(); 638 tv_ptr = &tv; 639 } 640 641 // Make a copy of the file descriptors to make sure we don't 642 // have another thread change these values out from under us 643 // and cause problems in the loop below where like in FS_SET() 644 const int data_fd = m_fd_recv; 645 const int pipe_fd = m_pipe_read; 646 647 if (data_fd >= 0) 648 { 649 const bool have_pipe_fd = pipe_fd >= 0; 650 651 while (data_fd == m_fd_recv) 652 { 653 const int nfds = std::max<int>(data_fd, pipe_fd) + 1; 654 llvm::SmallVector<fd_set, 1> read_fds; 655 read_fds.resize((nfds/FD_SETSIZE) + 1); 656 for (size_t i=0; i<read_fds.size(); ++i) 657 FD_ZERO (&read_fds[i]); 658 // FD_SET doesn't bounds check, it just happily walks off the end 659 // but we have taken care of making the extra storage with our 660 // SmallVector of fd_set objects 661 FD_SET (data_fd, read_fds.data()); 662 if (have_pipe_fd) 663 FD_SET (pipe_fd, read_fds.data()); 664 665 Error error; 666 667 if (log) 668 { 669 if (have_pipe_fd) 670 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...", 671 this, nfds, data_fd, pipe_fd, tv_ptr); 672 else 673 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...", 674 this, nfds, data_fd, tv_ptr); 675 } 676 677 const int num_set_fds = ::select (nfds, read_fds.data(), 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) => %d, error = %s", 687 this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString()); 688 else 689 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s", 690 this, nfds, data_fd, 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 // FD_ISSET is happy to deal with a something larger than 723 // a single fd_set. 724 if (FD_ISSET(data_fd, read_fds.data())) 725 return eConnectionStatusSuccess; 726 if (have_pipe_fd && FD_ISSET(pipe_fd, read_fds.data())) 727 { 728 // We got a command to exit. Read the data from that pipe: 729 char buffer[16]; 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 assert (bytes_read == 1 && buffer[0] == 'q'); 737 738 if (log) 739 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.", 740 this, (int) bytes_read, buffer); 741 742 return eConnectionStatusEndOfFile; 743 } 744 } 745 } 746 } 747 748 if (error_ptr) 749 error_ptr->SetErrorString("not connected"); 750 return eConnectionStatusLostConnection; 751} 752 753#else 754 755// This ConnectionFileDescriptor::BytesAvailable() uses select(). 756// 757// PROS: 758// - select is consistent across most unix platforms 759// CONS: 760// - only supports file descriptors up to FD_SETSIZE. This implementation 761// will assert if it runs into that hard limit to let users know that 762// another ConnectionFileDescriptor::BytesAvailable() should be used 763// or a new version of ConnectionFileDescriptor::BytesAvailable() should 764// be written for the system that is running into the limitations. MacOSX 765// uses kqueues, and there is a poll() based implementation below. 766 767ConnectionStatus 768ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) 769{ 770 // Don't need to take the mutex here separately since we are only called from Read. If we 771 // ever get used more generally we will need to lock here as well. 772 773 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 774 if (log) 775 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec); 776 struct timeval *tv_ptr; 777 struct timeval tv; 778 if (timeout_usec == UINT32_MAX) 779 { 780 // Infinite wait... 781 tv_ptr = NULL; 782 } 783 else 784 { 785 TimeValue time_value; 786 time_value.OffsetWithMicroSeconds (timeout_usec); 787 tv = time_value.GetAsTimeVal(); 788 tv_ptr = &tv; 789 } 790 791 // Make a copy of the file descriptors to make sure we don't 792 // have another thread change these values out from under us 793 // and cause problems in the loop below where like in FS_SET() 794 const int data_fd = m_fd_recv; 795 const int pipe_fd = m_pipe_read; 796 797 if (data_fd >= 0) 798 { 799 // If this assert fires off on MacOSX, we will need to switch to using 800 // libdispatch to read from file descriptors because poll() is causing 801 // kernel panics and if we exceed FD_SETSIZE we will have no choice... 802 assert (data_fd < FD_SETSIZE); 803 804 const bool have_pipe_fd = pipe_fd >= 0; 805 806 if (have_pipe_fd) 807 { 808 assert (pipe_fd < FD_SETSIZE); 809 } 810 811 while (data_fd == m_fd_recv) 812 { 813 fd_set read_fds; 814 FD_ZERO (&read_fds); 815 FD_SET (data_fd, &read_fds); 816 if (have_pipe_fd) 817 FD_SET (pipe_fd, &read_fds); 818 819 const int nfds = std::max<int>(data_fd, pipe_fd) + 1; 820 821 Error error; 822 823 if (log) 824 { 825 if (have_pipe_fd) 826 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...", 827 this, nfds, data_fd, pipe_fd, tv_ptr); 828 else 829 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...", 830 this, nfds, data_fd, tv_ptr); 831 } 832 833 const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr); 834 if (num_set_fds < 0) 835 error.SetErrorToErrno(); 836 else 837 error.Clear(); 838 839 if (log) 840 { 841 if (have_pipe_fd) 842 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) => %d, error = %s", 843 this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString()); 844 else 845 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s", 846 this, nfds, data_fd, tv_ptr, num_set_fds, error.AsCString()); 847 } 848 849 if (error_ptr) 850 *error_ptr = error; 851 852 if (error.Fail()) 853 { 854 switch (error.GetError()) 855 { 856 case EBADF: // One of the descriptor sets specified an invalid descriptor. 857 return eConnectionStatusLostConnection; 858 859 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. 860 default: // Other unknown error 861 return eConnectionStatusError; 862 863 case EAGAIN: // The kernel was (perhaps temporarily) unable to 864 // allocate the requested number of file descriptors, 865 // or we have non-blocking IO 866 case EINTR: // A signal was delivered before the time limit 867 // expired and before any of the selected events 868 // occurred. 869 break; // Lets keep reading to until we timeout 870 } 871 } 872 else if (num_set_fds == 0) 873 { 874 return eConnectionStatusTimedOut; 875 } 876 else if (num_set_fds > 0) 877 { 878 if (FD_ISSET(data_fd, &read_fds)) 879 return eConnectionStatusSuccess; 880 if (have_pipe_fd && FD_ISSET(pipe_fd, &read_fds)) 881 { 882 // We got a command to exit. Read the data from that pipe: 883 char buffer[16]; 884 ssize_t bytes_read; 885 886 do 887 { 888 bytes_read = ::read (pipe_fd, buffer, sizeof(buffer)); 889 } while (bytes_read < 0 && errno == EINTR); 890 assert (bytes_read == 1 && buffer[0] == 'q'); 891 892 if (log) 893 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.", 894 this, (int) bytes_read, buffer); 895 896 return eConnectionStatusEndOfFile; 897 } 898 } 899 } 900 } 901 902 if (error_ptr) 903 error_ptr->SetErrorString("not connected"); 904 return eConnectionStatusLostConnection; 905} 906 907#endif 908 909#if 0 910#include <poll.h> 911 912// This ConnectionFileDescriptor::BytesAvailable() uses poll(). poll() should NOT 913// be used on MacOSX as it has all sorts of restrictions on the types of file descriptors 914// that it doesn't support. 915// 916// There may be some systems that properly support poll() that could use this 917// implementation. I will let each system opt into this on their own. 918// 919// PROS: 920// - no restrictions on the fd value that is used 921// CONS: 922// - varies wildly from platform to platform in its implementation restrictions 923 924ConnectionStatus 925ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) 926{ 927 // Don't need to take the mutex here separately since we are only called from Read. If we 928 // ever get used more generally we will need to lock here as well. 929 930 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 931 if (log) 932 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec); 933 int timeout_msec = 0; 934 if (timeout_usec == UINT32_MAX) 935 { 936 // Infinite wait... 937 timeout_msec = -1; 938 } 939 else if (timeout_usec == 0) 940 { 941 // Return immediately, don't wait 942 timeout_msec = 0; 943 } 944 else 945 { 946 // Convert usec to msec 947 timeout_msec = (timeout_usec + 999) / 1000; 948 } 949 950 // Make a copy of the file descriptors to make sure we don't 951 // have another thread change these values out from under us 952 // and cause problems in the loop below where like in FS_SET() 953 const int data_fd = m_fd_recv; 954 const int pipe_fd = m_pipe_read; 955 956 // Make sure the file descriptor can be used with select as it 957 // must be in range 958 if (data_fd >= 0) 959 { 960 const bool have_pipe_fd = pipe_fd >= 0; 961 struct pollfd fds[2] = 962 { 963 { data_fd, POLLIN, 0 }, 964 { pipe_fd, POLLIN, 0 } 965 }; 966 const int nfds = have_pipe_fd ? 2 : 1; 967 Error error; 968 while (data_fd == m_fd_recv) 969 { 970 const int num_set_fds = ::poll (fds, nfds, timeout_msec); 971 972 if (num_set_fds < 0) 973 error.SetErrorToErrno(); 974 else 975 error.Clear(); 976 977 if (error_ptr) 978 *error_ptr = error; 979 980 if (log) 981 { 982 if (have_pipe_fd) 983 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN},{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n", 984 this, 985 data_fd, 986 pipe_fd, 987 nfds, 988 timeout_msec, 989 num_set_fds, 990 error.AsCString()); 991 else 992 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n", 993 this, 994 data_fd, 995 nfds, 996 timeout_msec, 997 num_set_fds, 998 error.AsCString()); 999 } 1000 1001 if (error.Fail()) 1002 { 1003 switch (error.GetError()) 1004 { 1005 case EBADF: // One of the descriptor sets specified an invalid descriptor. 1006 return eConnectionStatusLostConnection; 1007 1008 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. 1009 default: // Other unknown error 1010 return eConnectionStatusError; 1011 1012 case EAGAIN: // The kernel was (perhaps temporarily) unable to 1013 // allocate the requested number of file descriptors, 1014 // or we have non-blocking IO 1015 case EINTR: // A signal was delivered before the time limit 1016 // expired and before any of the selected events 1017 // occurred. 1018 break; // Lets keep reading to until we timeout 1019 } 1020 } 1021 else if (num_set_fds == 0) 1022 { 1023 return eConnectionStatusTimedOut; 1024 } 1025 else if (num_set_fds > 0) 1026 { 1027 if (fds[0].revents & POLLIN) 1028 return eConnectionStatusSuccess; 1029 if (fds[1].revents & POLLIN) 1030 { 1031 // We got a command to exit. Read the data from that pipe: 1032 char buffer[16]; 1033 ssize_t bytes_read; 1034 1035 do 1036 { 1037 bytes_read = ::read (pipe_fd, buffer, sizeof(buffer)); 1038 } while (bytes_read < 0 && errno == EINTR); 1039 assert (bytes_read == 1 && buffer[0] == 'q'); 1040 1041 if (log) 1042 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.", 1043 this, (int) bytes_read, buffer); 1044 1045 return eConnectionStatusEndOfFile; 1046 } 1047 } 1048 } 1049 } 1050 if (error_ptr) 1051 error_ptr->SetErrorString("not connected"); 1052 return eConnectionStatusLostConnection; 1053} 1054 1055#endif 1056 1057ConnectionStatus 1058ConnectionFileDescriptor::Close (int& fd, Error *error_ptr) 1059{ 1060 if (error_ptr) 1061 error_ptr->Clear(); 1062 bool success = true; 1063 // Avoid taking a lock if we can 1064 if (fd >= 0) 1065 { 1066 Mutex::Locker locker (m_mutex); 1067 // Check the FD after the lock is taken to ensure only one thread 1068 // can get into the close scope below 1069 if (fd >= 0) 1070 { 1071 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 1072 if (log) 1073 log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd); 1074 1075 success = ::close (fd) == 0; 1076 // A reference to a FD was passed in, set it to an invalid value 1077 fd = -1; 1078 if (!success && error_ptr) 1079 { 1080 // Only set the error if we have been asked to since something else 1081 // might have caused us to try and shut down the connection and may 1082 // have already set the error. 1083 error_ptr->SetErrorToErrno(); 1084 } 1085 } 1086 } 1087 if (success) 1088 return eConnectionStatusSuccess; 1089 else 1090 return eConnectionStatusError; 1091} 1092 1093ConnectionStatus 1094ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr) 1095{ 1096 ConnectionStatus result = eConnectionStatusError; 1097 struct sockaddr_un saddr_un; 1098 1099 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 1100 1101 int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0); 1102 if (listen_socket == -1) 1103 { 1104 if (error_ptr) 1105 error_ptr->SetErrorToErrno(); 1106 return eConnectionStatusError; 1107 } 1108 1109 saddr_un.sun_family = AF_UNIX; 1110 ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1); 1111 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0'; 1112#if defined(__APPLE__) || defined(__FreeBSD__) 1113 saddr_un.sun_len = SUN_LEN (&saddr_un); 1114#endif 1115 1116 if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0) 1117 { 1118 if (::listen (listen_socket, 5) == 0) 1119 { 1120 m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0); 1121 if (m_fd_send > 0) 1122 { 1123 m_should_close_fd = true; 1124 1125 if (error_ptr) 1126 error_ptr->Clear(); 1127 result = eConnectionStatusSuccess; 1128 } 1129 } 1130 } 1131 1132 if (result != eConnectionStatusSuccess) 1133 { 1134 if (error_ptr) 1135 error_ptr->SetErrorToErrno(); 1136 } 1137 // We are done with the listen port 1138 Close (listen_socket, NULL); 1139 return result; 1140} 1141 1142ConnectionStatus 1143ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr) 1144{ 1145 Disconnect (NULL); 1146 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 1147 1148 // Open the socket that was passed in as an option 1149 struct sockaddr_un saddr_un; 1150 m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0); 1151 if (m_fd_send == -1) 1152 { 1153 if (error_ptr) 1154 error_ptr->SetErrorToErrno(); 1155 return eConnectionStatusError; 1156 } 1157 1158 saddr_un.sun_family = AF_UNIX; 1159 ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1); 1160 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0'; 1161#if defined(__APPLE__) || defined(__FreeBSD__) 1162 saddr_un.sun_len = SUN_LEN (&saddr_un); 1163#endif 1164 1165 if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 1166 { 1167 if (error_ptr) 1168 error_ptr->SetErrorToErrno(); 1169 Disconnect (NULL); 1170 return eConnectionStatusError; 1171 } 1172 if (error_ptr) 1173 error_ptr->Clear(); 1174 return eConnectionStatusSuccess; 1175} 1176 1177ConnectionStatus 1178ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr) 1179{ 1180 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 1181 if (log) 1182 log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num); 1183 1184 Disconnect (NULL); 1185 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 1186 int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 1187 if (listen_port == -1) 1188 { 1189 if (error_ptr) 1190 error_ptr->SetErrorToErrno(); 1191 return eConnectionStatusError; 1192 } 1193 1194 // enable local address reuse 1195 SetSocketOption (listen_port, SOL_SOCKET, SO_REUSEADDR, 1); 1196 1197 SocketAddress localhost; 1198 if (localhost.SetToLocalhost (AF_INET, listen_port_num)) 1199 { 1200 int err = ::bind (listen_port, localhost, localhost.GetLength()); 1201 if (err == -1) 1202 { 1203 if (error_ptr) 1204 error_ptr->SetErrorToErrno(); 1205 Close (listen_port, NULL); 1206 return eConnectionStatusError; 1207 } 1208 1209 err = ::listen (listen_port, 1); 1210 if (err == -1) 1211 { 1212 if (error_ptr) 1213 error_ptr->SetErrorToErrno(); 1214 Close (listen_port, NULL); 1215 return eConnectionStatusError; 1216 } 1217 1218 m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0); 1219 if (m_fd_send == -1) 1220 { 1221 if (error_ptr) 1222 error_ptr->SetErrorToErrno(); 1223 Close (listen_port, NULL); 1224 return eConnectionStatusError; 1225 } 1226 } 1227 1228 // We are done with the listen port 1229 Close (listen_port, NULL); 1230 1231 m_should_close_fd = true; 1232 1233 // Keep our TCP packets coming without any delays. 1234 SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1); 1235 if (error_ptr) 1236 error_ptr->Clear(); 1237 return eConnectionStatusSuccess; 1238} 1239 1240ConnectionStatus 1241ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr) 1242{ 1243 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 1244 if (log) 1245 log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port); 1246 Disconnect (NULL); 1247 1248 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 1249 std::string host_str; 1250 std::string port_str; 1251 int32_t port = INT32_MIN; 1252 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr)) 1253 return eConnectionStatusError; 1254 1255 // Create the socket 1256 m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 1257 if (m_fd_send == -1) 1258 { 1259 if (error_ptr) 1260 error_ptr->SetErrorToErrno(); 1261 return eConnectionStatusError; 1262 } 1263 1264 m_should_close_fd = true; 1265 1266 // Enable local address reuse 1267 SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1); 1268 1269 struct sockaddr_in sa; 1270 ::memset (&sa, 0, sizeof (sa)); 1271 sa.sin_family = AF_INET; 1272 sa.sin_port = htons (port); 1273 1274 int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr); 1275 1276 if (inet_pton_result <= 0) 1277 { 1278 struct hostent *host_entry = gethostbyname (host_str.c_str()); 1279 if (host_entry) 1280 host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list); 1281 inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr); 1282 if (inet_pton_result <= 0) 1283 { 1284 1285 if (error_ptr) 1286 { 1287 if (inet_pton_result == -1) 1288 error_ptr->SetErrorToErrno(); 1289 else 1290 error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str()); 1291 } 1292 Disconnect (NULL); 1293 1294 return eConnectionStatusError; 1295 } 1296 } 1297 1298 if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa))) 1299 { 1300 if (error_ptr) 1301 error_ptr->SetErrorToErrno(); 1302 Disconnect (NULL); 1303 1304 return eConnectionStatusError; 1305 } 1306 1307 // Keep our TCP packets coming without any delays. 1308 SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1); 1309 if (error_ptr) 1310 error_ptr->Clear(); 1311 return eConnectionStatusSuccess; 1312} 1313 1314ConnectionStatus 1315ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr) 1316{ 1317 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 1318 if (log) 1319 log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port); 1320 Disconnect (NULL); 1321 1322 m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP; 1323 1324 std::string host_str; 1325 std::string port_str; 1326 int32_t port = INT32_MIN; 1327 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr)) 1328 return eConnectionStatusError; 1329 1330 // Setup the receiving end of the UDP connection on this localhost 1331 // on port zero. After we bind to port zero we can read the port. 1332 m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0); 1333 if (m_fd_recv == -1) 1334 { 1335 // Socket creation failed... 1336 if (error_ptr) 1337 error_ptr->SetErrorToErrno(); 1338 } 1339 else 1340 { 1341 // Socket was created, now lets bind to the requested port 1342 SocketAddress addr; 1343 addr.SetToLocalhost (AF_INET, 0); 1344 1345 if (::bind (m_fd_recv, addr, addr.GetLength()) == -1) 1346 { 1347 // Bind failed... 1348 if (error_ptr) 1349 error_ptr->SetErrorToErrno(); 1350 Disconnect (NULL); 1351 } 1352 } 1353 1354 if (m_fd_recv == -1) 1355 return eConnectionStatusError; 1356 1357 // At this point we have setup the recieve port, now we need to 1358 // setup the UDP send socket 1359 1360 struct addrinfo hints; 1361 struct addrinfo *service_info_list = NULL; 1362 1363 ::memset (&hints, 0, sizeof(hints)); 1364 hints.ai_family = AF_INET; 1365 hints.ai_socktype = SOCK_DGRAM; 1366 int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list); 1367 if (err != 0) 1368 { 1369 if (error_ptr) 1370 error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", 1371 host_str.c_str(), 1372 port_str.c_str(), 1373 err, 1374 gai_strerror(err)); 1375 Disconnect (NULL); 1376 return eConnectionStatusError; 1377 } 1378 1379 for (struct addrinfo *service_info_ptr = service_info_list; 1380 service_info_ptr != NULL; 1381 service_info_ptr = service_info_ptr->ai_next) 1382 { 1383 m_fd_send = ::socket (service_info_ptr->ai_family, 1384 service_info_ptr->ai_socktype, 1385 service_info_ptr->ai_protocol); 1386 1387 if (m_fd_send != -1) 1388 { 1389 m_udp_send_sockaddr = service_info_ptr; 1390 break; 1391 } 1392 else 1393 continue; 1394 } 1395 1396 :: freeaddrinfo (service_info_list); 1397 1398 if (m_fd_send == -1) 1399 { 1400 Disconnect (NULL); 1401 return eConnectionStatusError; 1402 } 1403 1404 if (error_ptr) 1405 error_ptr->Clear(); 1406 1407 m_should_close_fd = true; 1408 return eConnectionStatusSuccess; 1409} 1410 1411#if defined(__MINGW32__) || defined(__MINGW64__) 1412typedef const char * set_socket_option_arg_type; 1413typedef char * get_socket_option_arg_type; 1414#else // #if defined(__MINGW32__) || defined(__MINGW64__) 1415typedef const void * set_socket_option_arg_type; 1416typedef void * get_socket_option_arg_type; 1417#endif // #if defined(__MINGW32__) || defined(__MINGW64__) 1418 1419int 1420ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value) 1421{ 1422 get_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value); 1423 socklen_t option_value_size = sizeof(int); 1424 return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size); 1425} 1426 1427int 1428ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value) 1429{ 1430 set_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value); 1431 return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value)); 1432} 1433 1434bool 1435ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec) 1436{ 1437 switch (m_fd_recv_type) 1438 { 1439 case eFDTypeFile: // Other FD requireing read/write 1440 break; 1441 1442 case eFDTypeSocket: // Socket requiring send/recv 1443 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom 1444 { 1445 // Check in case timeout for m_fd has already been set to this value 1446 if (timeout_usec == m_socket_timeout_usec) 1447 return true; 1448 //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec); 1449 1450 struct timeval timeout; 1451 if (timeout_usec == UINT32_MAX) 1452 { 1453 timeout.tv_sec = 0; 1454 timeout.tv_usec = 0; 1455 } 1456 else if (timeout_usec == 0) 1457 { 1458 // Sending in zero does an infinite timeout, so set this as low 1459 // as we can go to get an effective zero timeout... 1460 timeout.tv_sec = 0; 1461 timeout.tv_usec = 1; 1462 } 1463 else 1464 { 1465 timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec; 1466 timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec; 1467 } 1468 if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0) 1469 { 1470 m_socket_timeout_usec = timeout_usec; 1471 return true; 1472 } 1473 } 1474 } 1475 return false; 1476} 1477 1478in_port_t 1479ConnectionFileDescriptor::GetSocketPort (int fd) 1480{ 1481 // We bound to port zero, so we need to figure out which port we actually bound to 1482 SocketAddress sock_addr; 1483 socklen_t sock_addr_len = sock_addr.GetMaxLength (); 1484 if (::getsockname (fd, sock_addr, &sock_addr_len) == 0) 1485 return sock_addr.GetPort (); 1486 1487 return 0; 1488} 1489 1490// If the read file descriptor is a socket, then return 1491// the port number that is being used by the socket. 1492in_port_t 1493ConnectionFileDescriptor::GetReadPort () const 1494{ 1495 return ConnectionFileDescriptor::GetSocketPort (m_fd_recv); 1496} 1497 1498// If the write file descriptor is a socket, then return 1499// the port number that is being used by the socket. 1500in_port_t 1501ConnectionFileDescriptor::GetWritePort () const 1502{ 1503 return ConnectionFileDescriptor::GetSocketPort (m_fd_send); 1504} 1505 1506 1507