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