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, &regex_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