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