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