ConnectionFileDescriptor.cpp revision 3ce4df5be58f188270210927a6e25a0192b60efc
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#include "lldb/Core/ConnectionFileDescriptor.h"
11
12// C Includes
13#include <errno.h>
14#include <fcntl.h>
15#include <arpa/inet.h>
16#include <netdb.h>
17#include <netinet/in.h>
18#include <netinet/tcp.h>
19#include <sys/socket.h>
20#include <sys/un.h>
21#include <sys/types.h>
22#include <string.h>
23#include <stdlib.h>
24#include <unistd.h>
25
26// C++ Includes
27// Other libraries and framework includes
28// Project includes
29#include "lldb/lldb-private-log.h"
30#include "lldb/Interpreter/Args.h"
31#include "lldb/Core/Communication.h"
32#include "lldb/Core/Log.h"
33#include "lldb/Core/RegularExpression.h"
34#include "lldb/Core/Timer.h"
35
36using namespace lldb;
37using namespace lldb_private;
38
39static bool
40DecodeHostAndPort (const char *host_and_port,
41                   std::string &host_str,
42                   std::string &port_str,
43                   int32_t& port,
44                   Error *error_ptr)
45{
46    RegularExpression regex ("([^:]+):([0-9]+)");
47    if (regex.Execute (host_and_port, 2))
48    {
49        if (regex.GetMatchAtIndex (host_and_port, 1, host_str) &&
50            regex.GetMatchAtIndex (host_and_port, 2, port_str))
51        {
52            port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
53            if (port != INT32_MIN)
54            {
55                if (error_ptr)
56                    error_ptr->Clear();
57                return true;
58            }
59        }
60    }
61    host_str.clear();
62    port_str.clear();
63    port = INT32_MIN;
64    if (error_ptr)
65        error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
66    return false;
67}
68
69ConnectionFileDescriptor::ConnectionFileDescriptor () :
70    Connection(),
71    m_fd_send (-1),
72    m_fd_recv (-1),
73    m_fd_send_type (eFDTypeFile),
74    m_fd_recv_type (eFDTypeFile),
75    m_udp_send_sockaddr (),
76    m_should_close_fd (false),
77    m_socket_timeout_usec(0),
78    m_command_fd_send(-1),
79    m_command_fd_receive(-1),
80    m_mutex (Mutex::eMutexTypeRecursive)
81{
82    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
83    if (log)
84        log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", this);
85}
86
87ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
88    Connection(),
89    m_fd_send (fd),
90    m_fd_recv (fd),
91    m_fd_send_type (eFDTypeFile),
92    m_fd_recv_type (eFDTypeFile),
93    m_udp_send_sockaddr (),
94    m_should_close_fd (owns_fd),
95    m_socket_timeout_usec(0),
96    m_command_fd_send(-1),
97    m_command_fd_receive(-1),
98    m_mutex (Mutex::eMutexTypeRecursive)
99{
100    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
101    if (log)
102        log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", this, fd, owns_fd);
103}
104
105
106ConnectionFileDescriptor::~ConnectionFileDescriptor ()
107{
108    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
109    if (log)
110        log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", this);
111    Disconnect (NULL);
112    CloseCommandFileDescriptor ();
113}
114
115void
116ConnectionFileDescriptor::InitializeCommandFileDescriptor ()
117{
118    CloseCommandFileDescriptor();
119
120    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
121    // Make the command file descriptor here:
122    int filedes[2];
123    int result = pipe (filedes);
124    if (result != 0)
125    {
126        if (log)
127            log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor () - could not make pipe: %s",
128                         this,
129                         strerror(errno));
130    }
131    else
132    {
133        m_command_fd_receive = filedes[0];
134        m_command_fd_send    = filedes[1];
135    }
136}
137
138void
139ConnectionFileDescriptor::CloseCommandFileDescriptor ()
140{
141    if (m_command_fd_receive != -1)
142    {
143        close (m_command_fd_receive);
144        m_command_fd_receive = -1;
145    }
146
147    if (m_command_fd_send != -1)
148    {
149        close (m_command_fd_send);
150        m_command_fd_send = -1;
151    }
152}
153
154bool
155ConnectionFileDescriptor::IsConnected () const
156{
157    return m_fd_send >= 0 || m_fd_recv >= 0;
158}
159
160ConnectionStatus
161ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
162{
163    Mutex::Locker locker (m_mutex);
164    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
165    if (log)
166        log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", this, s);
167
168    InitializeCommandFileDescriptor();
169
170    if (s && s[0])
171    {
172        char *end = NULL;
173        if (strstr(s, "listen://"))
174        {
175            // listen://HOST:PORT
176            unsigned long listen_port = ::strtoul(s + strlen("listen://"), &end, 0);
177            return SocketListen (listen_port, error_ptr);
178        }
179        else if (strstr(s, "unix-accept://"))
180        {
181            // unix://SOCKNAME
182            return NamedSocketAccept (s + strlen("unix-accept://"), error_ptr);
183        }
184        else if (strstr(s, "connect://"))
185        {
186            return ConnectTCP (s + strlen("connect://"), error_ptr);
187        }
188        else if (strstr(s, "tcp-connect://"))
189        {
190            return ConnectTCP (s + strlen("tcp-connect://"), error_ptr);
191        }
192        else if (strstr(s, "udp://"))
193        {
194            return ConnectUDP (s + strlen("udp://"), error_ptr);
195        }
196        else if (strstr(s, "fd://"))
197        {
198            // Just passing a native file descriptor within this current process
199            // that is already opened (possibly from a service or other source).
200            s += strlen ("fd://");
201            bool success = false;
202            m_fd_send = m_fd_recv = Args::StringToSInt32 (s, -1, 0, &success);
203
204            if (success)
205            {
206                // We have what looks to be a valid file descriptor, but we
207                // should make sure it is. We currently are doing this by trying to
208                // get the flags from the file descriptor and making sure it
209                // isn't a bad fd.
210                errno = 0;
211                int flags = ::fcntl (m_fd_send, F_GETFL, 0);
212                if (flags == -1 || errno == EBADF)
213                {
214                    if (error_ptr)
215                        error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s);
216                    m_fd_send = m_fd_recv = -1;
217                    return eConnectionStatusError;
218                }
219                else
220                {
221                    // Try and get a socket option from this file descriptor to
222                    // see if this is a socket and set m_is_socket accordingly.
223                    int resuse;
224                    bool is_socket = GetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
225                    if (is_socket)
226                        m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
227                    // Don't take ownership of a file descriptor that gets passed
228                    // to us since someone else opened the file descriptor and
229                    // handed it to us.
230                    // TODO: Since are using a URL to open connection we should
231                    // eventually parse options using the web standard where we
232                    // have "fd://123?opt1=value;opt2=value" and we can have an
233                    // option be "owns=1" or "owns=0" or something like this to
234                    // allow us to specify this. For now, we assume we must
235                    // assume we don't own it.
236                    m_should_close_fd = false;
237                    return eConnectionStatusSuccess;
238                }
239            }
240
241            if (error_ptr)
242                error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s);
243            m_fd_send = m_fd_recv = -1;
244            return eConnectionStatusError;
245        }
246        else if (strstr(s, "file://"))
247        {
248            // file:///PATH
249            const char *path = s + strlen("file://");
250            do
251            {
252                m_fd_send = m_fd_recv = ::open (path, O_RDWR);
253            } while (m_fd_send == -1 && errno == EINTR);
254            if (m_fd_send == -1)
255            {
256                if (error_ptr)
257                    error_ptr->SetErrorToErrno();
258                return eConnectionStatusError;
259            }
260
261            int flags = ::fcntl (m_fd_send, F_GETFL, 0);
262            if (flags >= 0)
263            {
264                if ((flags & O_NONBLOCK) == 0)
265                {
266                    flags |= O_NONBLOCK;
267                    ::fcntl (m_fd_send, F_SETFL, flags);
268                }
269            }
270            m_should_close_fd = true;
271            return eConnectionStatusSuccess;
272        }
273        if (error_ptr)
274            error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s);
275        return eConnectionStatusError;
276    }
277    if (error_ptr)
278        error_ptr->SetErrorString("invalid connect arguments");
279    return eConnectionStatusError;
280}
281
282ConnectionStatus
283ConnectionFileDescriptor::Disconnect (Error *error_ptr)
284{
285    Mutex::Locker locker (m_mutex);
286    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
287    if (log)
288        log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);
289
290    ConnectionStatus status = eConnectionStatusSuccess;
291
292    if (m_fd_send >= 0 || m_fd_recv >= 0)
293    {
294        if (m_should_close_fd == false)
295        {
296            m_fd_send = m_fd_recv = -1;
297        }
298        else
299        {
300            if (m_fd_send == m_fd_recv)
301            {
302                // Both file descriptors are the same, only close one
303                m_fd_recv = -1;
304                status = Close (m_fd_send, error_ptr);
305            }
306            else
307            {
308                // File descriptors are the different, close both if needed
309                if (m_fd_send >= 0)
310                    status = Close (m_fd_send, error_ptr);
311                if (m_fd_recv >= 0)
312                {
313                    ConnectionStatus recv_status = Close (m_fd_recv, error_ptr);
314                    if (status == eConnectionStatusSuccess)
315                        status = recv_status;
316                }
317            }
318        }
319
320        // Now write a byte to the command pipe to wake our Reader if it is stuck in read.
321        if (m_command_fd_send != -1 )
322        {
323            write (m_command_fd_send, "q", 1);
324            close (m_command_fd_send);
325            m_command_fd_send = -1;
326        }
327    }
328    return status;
329}
330
331size_t
332ConnectionFileDescriptor::Read (void *dst,
333                                size_t dst_len,
334                                uint32_t timeout_usec,
335                                ConnectionStatus &status,
336                                Error *error_ptr)
337{
338    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
339    if (log)
340        log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu)...",
341                     this, m_fd_recv, dst, dst_len);
342
343    ssize_t bytes_read = 0;
344
345    status = BytesAvailable (timeout_usec, error_ptr);
346    if (status == eConnectionStatusSuccess)
347    {
348        do
349        {
350            bytes_read = ::read (m_fd_recv, dst, dst_len);
351        } while (bytes_read < 0 && errno == EINTR);
352    }
353
354    if (status != eConnectionStatusSuccess)
355        return 0;
356
357    Error error;
358    if (bytes_read == 0)
359    {
360        error.Clear(); // End-of-file.  Do not automatically close; pass along for the end-of-file handlers.
361        status = eConnectionStatusEndOfFile;
362    }
363    else if (bytes_read < 0)
364    {
365        error.SetErrorToErrno();
366    }
367    else
368    {
369        error.Clear();
370    }
371
372    if (log)
373        log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu) => %zi, error = %s",
374                     this,
375                     m_fd_recv,
376                     dst,
377                     dst_len,
378                     bytes_read,
379                     error.AsCString());
380
381    if (error_ptr)
382        *error_ptr = error;
383
384    if (error.Fail())
385    {
386        uint32_t error_value = error.GetError();
387        switch (error_value)
388        {
389        case EAGAIN:    // The file was marked for non-blocking I/O, and no data were ready to be read.
390            if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP)
391                status = eConnectionStatusTimedOut;
392            else
393                status = eConnectionStatusSuccess;
394            return 0;
395
396        case EFAULT:    // Buf points outside the allocated address space.
397        case EINTR:     // A read from a slow device was interrupted before any data arrived by the delivery of a signal.
398        case EINVAL:    // The pointer associated with fildes was negative.
399        case EIO:       // An I/O error occurred while reading from the file system.
400                        // The process group is orphaned.
401                        // The file is a regular file, nbyte is greater than 0,
402                        // the starting position is before the end-of-file, and
403                        // the starting position is greater than or equal to the
404                        // offset maximum established for the open file
405                        // descriptor associated with fildes.
406        case EISDIR:    // An attempt is made to read a directory.
407        case ENOBUFS:   // An attempt to allocate a memory buffer fails.
408        case ENOMEM:    // Insufficient memory is available.
409            status = eConnectionStatusError;
410            break;  // Break to close....
411
412        case ENOENT:    // no such file or directory
413        case EBADF:     // fildes is not a valid file or socket descriptor open for reading.
414        case ENXIO:     // An action is requested of a device that does not exist..
415                        // A requested action cannot be performed by the device.
416        case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
417        case ENOTCONN:  // A read is attempted on an unconnected socket.
418            status = eConnectionStatusLostConnection;
419            break;  // Break to close....
420
421        case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket.
422            status = eConnectionStatusTimedOut;
423            return 0;
424        }
425
426        //Disconnect (NULL);
427        return 0;
428    }
429    return bytes_read;
430}
431
432size_t
433ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
434{
435    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
436    if (log)
437        log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %zu)", this, src, src_len);
438
439    if (!IsConnected ())
440    {
441        if (error_ptr)
442            error_ptr->SetErrorString("not connected");
443        status = eConnectionStatusNoConnection;
444        return 0;
445    }
446
447
448    Error error;
449
450    ssize_t bytes_sent = 0;
451
452    switch (m_fd_send_type)
453    {
454        case eFDTypeFile:       // Other FD requireing read/write
455            do
456            {
457                bytes_sent = ::write (m_fd_send, src, src_len);
458            } while (bytes_sent < 0 && errno == EINTR);
459            break;
460
461        case eFDTypeSocket:     // Socket requiring send/recv
462            do
463            {
464                bytes_sent = ::send (m_fd_send, src, src_len, 0);
465            } while (bytes_sent < 0 && errno == EINTR);
466            break;
467
468        case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
469            assert (m_udp_send_sockaddr.GetFamily() != 0);
470            do
471            {
472                bytes_sent = ::sendto (m_fd_send,
473                                       src,
474                                       src_len,
475                                       0,
476                                       m_udp_send_sockaddr,
477                                       m_udp_send_sockaddr.GetLength());
478            } while (bytes_sent < 0 && errno == EINTR);
479            break;
480    }
481
482    if (bytes_sent < 0)
483        error.SetErrorToErrno ();
484    else
485        error.Clear ();
486
487    if (log)
488    {
489        switch (m_fd_send_type)
490        {
491            case eFDTypeFile:       // Other FD requireing read/write
492                log->Printf ("%p ConnectionFileDescriptor::Write()  ::write (fd = %i, src = %p, src_len = %zu) => %zi (error = %s)",
493                             this,
494                             m_fd_send,
495                             src,
496                             src_len,
497                             bytes_sent,
498                             error.AsCString());
499                break;
500
501            case eFDTypeSocket:     // Socket requiring send/recv
502                log->Printf ("%p ConnectionFileDescriptor::Write()  ::send (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
503                             this,
504                             m_fd_send,
505                             src,
506                             src_len,
507                             bytes_sent,
508                             error.AsCString());
509                break;
510
511            case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
512                log->Printf ("%p ConnectionFileDescriptor::Write()  ::sendto (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
513                             this,
514                             m_fd_send,
515                             src,
516                             src_len,
517                             bytes_sent,
518                             error.AsCString());
519                break;
520        }
521    }
522
523    if (error_ptr)
524        *error_ptr = error;
525
526    if (error.Fail())
527    {
528        switch (error.GetError())
529        {
530        case EAGAIN:
531        case EINTR:
532            status = eConnectionStatusSuccess;
533            return 0;
534
535        case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
536        case ENOTCONN:  // A read is attempted on an unconnected socket.
537            status = eConnectionStatusLostConnection;
538            break;  // Break to close....
539
540        default:
541            status = eConnectionStatusError;
542            break;  // Break to close....
543        }
544
545        //Disconnect (NULL);
546        return 0;
547    }
548
549    status = eConnectionStatusSuccess;
550    return bytes_sent;
551}
552
553ConnectionStatus
554ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
555{
556    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
557    if (log)
558        log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec);
559    struct timeval *tv_ptr;
560    struct timeval tv;
561    if (timeout_usec == UINT32_MAX)
562    {
563        // Infinite wait...
564        tv_ptr = NULL;
565    }
566    else
567    {
568        TimeValue time_value;
569        time_value.OffsetWithMicroSeconds (timeout_usec);
570        tv = time_value.GetAsTimeVal();
571        tv_ptr = &tv;
572    }
573
574    while (IsConnected())
575    {
576        fd_set read_fds;
577        FD_ZERO (&read_fds);
578        FD_SET (m_fd_recv, &read_fds);
579        if (m_command_fd_receive != -1)
580            FD_SET (m_command_fd_receive, &read_fds);
581        int nfds = (m_fd_recv > m_command_fd_receive ? m_fd_recv : m_command_fd_receive) + 1;
582
583        Error error;
584
585
586        if (log)
587            log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...",
588                        this, nfds, m_fd_recv, tv_ptr);
589
590        const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr);
591        if (num_set_fds < 0)
592            error.SetErrorToErrno();
593        else
594            error.Clear();
595
596        if (log)
597            log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s",
598                        this, nfds, m_fd_recv, tv_ptr, num_set_fds, error.AsCString());
599
600        if (error_ptr)
601            *error_ptr = error;
602
603        if (error.Fail())
604        {
605            switch (error.GetError())
606            {
607            case EBADF:     // One of the descriptor sets specified an invalid descriptor.
608                return eConnectionStatusLostConnection;
609
610            case EINVAL:    // The specified time limit is invalid. One of its components is negative or too large.
611            default:        // Other unknown error
612                return eConnectionStatusError;
613
614            case EAGAIN:    // The kernel was (perhaps temporarily) unable to
615                            // allocate the requested number of file descriptors,
616                            // or we have non-blocking IO
617            case EINTR:     // A signal was delivered before the time limit
618                            // expired and before any of the selected events
619                            // occurred.
620                break;      // Lets keep reading to until we timeout
621            }
622        }
623        else if (num_set_fds == 0)
624        {
625            return eConnectionStatusTimedOut;
626        }
627        else if (num_set_fds > 0)
628        {
629            if (m_command_fd_receive != -1 && FD_ISSET(m_command_fd_receive, &read_fds))
630            {
631                // We got a command to exit.  Read the data from that pipe:
632                char buffer[16];
633                ssize_t bytes_read;
634
635                do
636                {
637                    bytes_read = ::read (m_command_fd_receive, buffer, sizeof(buffer));
638                } while (bytes_read < 0 && errno == EINTR);
639                assert (bytes_read == 1 && buffer[0] == 'q');
640
641                if (log)
642                    log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
643                                this, (int) bytes_read, buffer);
644
645                return eConnectionStatusEndOfFile;
646            }
647            else
648                return eConnectionStatusSuccess;
649        }
650    }
651
652    if (error_ptr)
653        error_ptr->SetErrorString("not connected");
654    return eConnectionStatusLostConnection;
655}
656
657ConnectionStatus
658ConnectionFileDescriptor::Close (int& fd, Error *error_ptr)
659{
660    if (error_ptr)
661        error_ptr->Clear();
662    bool success = true;
663    // Avoid taking a lock if we can
664    if (fd >= 0)
665    {
666        Mutex::Locker locker (m_mutex);
667        // Check the FD after the lock is taken to ensure only one thread
668        // can get into the close scope below
669        if (fd >= 0)
670        {
671            LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
672            if (log)
673                log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd);
674
675            success = ::close (fd) == 0;
676            // A reference to a FD was passed in, set it to an invalid value
677            fd = -1;
678            if (!success && error_ptr)
679            {
680                // Only set the error if we have been asked to since something else
681                // might have caused us to try and shut down the connection and may
682                // have already set the error.
683                error_ptr->SetErrorToErrno();
684            }
685        }
686    }
687    if (success)
688        return eConnectionStatusSuccess;
689    else
690        return eConnectionStatusError;
691}
692
693ConnectionStatus
694ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr)
695{
696    ConnectionStatus result = eConnectionStatusError;
697    struct sockaddr_un saddr_un;
698
699    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
700
701    int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0);
702    if (listen_socket == -1)
703    {
704        if (error_ptr)
705            error_ptr->SetErrorToErrno();
706        return eConnectionStatusError;
707    }
708
709    saddr_un.sun_family = AF_UNIX;
710    ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
711    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
712#if defined(__APPLE__) || defined(__FreeBSD__)
713    saddr_un.sun_len = SUN_LEN (&saddr_un);
714#endif
715
716    if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0)
717    {
718        if (::listen (listen_socket, 5) == 0)
719        {
720            m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0);
721            if (m_fd_send > 0)
722            {
723                m_should_close_fd = true;
724
725                if (error_ptr)
726                    error_ptr->Clear();
727                result = eConnectionStatusSuccess;
728            }
729        }
730    }
731
732    if (result != eConnectionStatusSuccess)
733    {
734        if (error_ptr)
735            error_ptr->SetErrorToErrno();
736    }
737    // We are done with the listen port
738    Close (listen_socket, NULL);
739    return result;
740}
741
742ConnectionStatus
743ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr)
744{
745    Disconnect (NULL);
746    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
747
748    // Open the socket that was passed in as an option
749    struct sockaddr_un saddr_un;
750    m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0);
751    if (m_fd_send == -1)
752    {
753        if (error_ptr)
754            error_ptr->SetErrorToErrno();
755        return eConnectionStatusError;
756    }
757
758    saddr_un.sun_family = AF_UNIX;
759    ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
760    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
761#if defined(__APPLE__) || defined(__FreeBSD__)
762    saddr_un.sun_len = SUN_LEN (&saddr_un);
763#endif
764
765    if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
766    {
767        if (error_ptr)
768            error_ptr->SetErrorToErrno();
769        Disconnect (NULL);
770        return eConnectionStatusError;
771    }
772    if (error_ptr)
773        error_ptr->Clear();
774    return eConnectionStatusSuccess;
775}
776
777ConnectionStatus
778ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
779{
780    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
781    if (log)
782        log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num);
783
784    Disconnect (NULL);
785    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
786    int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
787    if (listen_port == -1)
788    {
789        if (error_ptr)
790            error_ptr->SetErrorToErrno();
791        return eConnectionStatusError;
792    }
793
794    // enable local address reuse
795    SetSocketOption (listen_port, SOL_SOCKET, SO_REUSEADDR, 1);
796
797    SocketAddress localhost;
798    if (localhost.SetToLocalhost (AF_INET, listen_port_num))
799    {
800        int err = ::bind (listen_port, localhost, localhost.GetLength());
801        if (err == -1)
802        {
803            if (error_ptr)
804                error_ptr->SetErrorToErrno();
805            Close (listen_port, NULL);
806            return eConnectionStatusError;
807        }
808
809        err = ::listen (listen_port, 1);
810        if (err == -1)
811        {
812            if (error_ptr)
813                error_ptr->SetErrorToErrno();
814            Close (listen_port, NULL);
815            return eConnectionStatusError;
816        }
817
818        m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0);
819        if (m_fd_send == -1)
820        {
821            if (error_ptr)
822                error_ptr->SetErrorToErrno();
823            Close (listen_port, NULL);
824            return eConnectionStatusError;
825        }
826    }
827
828    // We are done with the listen port
829    Close (listen_port, NULL);
830
831    m_should_close_fd = true;
832
833    // Keep our TCP packets coming without any delays.
834    SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
835    if (error_ptr)
836        error_ptr->Clear();
837    return eConnectionStatusSuccess;
838}
839
840ConnectionStatus
841ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
842{
843    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
844    if (log)
845        log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port);
846    Disconnect (NULL);
847
848    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
849    std::string host_str;
850    std::string port_str;
851    int32_t port = INT32_MIN;
852    if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
853        return eConnectionStatusError;
854
855    // Create the socket
856    m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
857    if (m_fd_send == -1)
858    {
859        if (error_ptr)
860            error_ptr->SetErrorToErrno();
861        return eConnectionStatusError;
862    }
863
864    m_should_close_fd = true;
865
866    // Enable local address reuse
867    SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1);
868
869    struct sockaddr_in sa;
870    ::memset (&sa, 0, sizeof (sa));
871    sa.sin_family = AF_INET;
872    sa.sin_port = htons (port);
873
874    int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
875
876    if (inet_pton_result <= 0)
877    {
878        struct hostent *host_entry = gethostbyname (host_str.c_str());
879        if (host_entry)
880            host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
881        inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
882        if (inet_pton_result <= 0)
883        {
884
885            if (error_ptr)
886            {
887                if (inet_pton_result == -1)
888                    error_ptr->SetErrorToErrno();
889                else
890                    error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
891            }
892            Disconnect (NULL);
893
894            return eConnectionStatusError;
895        }
896    }
897
898    if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa)))
899    {
900        if (error_ptr)
901            error_ptr->SetErrorToErrno();
902        Disconnect (NULL);
903
904        return eConnectionStatusError;
905    }
906
907    // Keep our TCP packets coming without any delays.
908    SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
909    if (error_ptr)
910        error_ptr->Clear();
911    return eConnectionStatusSuccess;
912}
913
914ConnectionStatus
915ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
916{
917    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
918    if (log)
919        log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port);
920    Disconnect (NULL);
921
922    m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP;
923
924    std::string host_str;
925    std::string port_str;
926    int32_t port = INT32_MIN;
927    if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
928        return eConnectionStatusError;
929
930    // Setup the receiving end of the UDP connection on this localhost
931    // on port zero. After we bind to port zero we can read the port.
932    m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0);
933    if (m_fd_recv == -1)
934    {
935        // Socket creation failed...
936        if (error_ptr)
937            error_ptr->SetErrorToErrno();
938    }
939    else
940    {
941        // Socket was created, now lets bind to the requested port
942        SocketAddress addr;
943        addr.SetToLocalhost (AF_INET, 0);
944
945        if (::bind (m_fd_recv, addr, addr.GetLength()) == -1)
946        {
947            // Bind failed...
948            if (error_ptr)
949                error_ptr->SetErrorToErrno();
950            Disconnect (NULL);
951        }
952    }
953
954    if (m_fd_recv == -1)
955        return eConnectionStatusError;
956
957    // At this point we have setup the recieve port, now we need to
958    // setup the UDP send socket
959
960    struct addrinfo hints;
961    struct addrinfo *service_info_list = NULL;
962
963    ::memset (&hints, 0, sizeof(hints));
964    hints.ai_family = AF_INET;
965    hints.ai_socktype = SOCK_DGRAM;
966    int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
967    if (err != 0)
968    {
969        if (error_ptr)
970            error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
971                                                host_str.c_str(),
972                                                port_str.c_str(),
973                                                err,
974                                                gai_strerror(err));
975        Disconnect (NULL);
976        return eConnectionStatusError;
977    }
978
979    for (struct addrinfo *service_info_ptr = service_info_list;
980         service_info_ptr != NULL;
981         service_info_ptr = service_info_ptr->ai_next)
982    {
983        m_fd_send = ::socket (service_info_ptr->ai_family,
984                              service_info_ptr->ai_socktype,
985                              service_info_ptr->ai_protocol);
986
987        if (m_fd_send != -1)
988        {
989            m_udp_send_sockaddr = service_info_ptr;
990            break;
991        }
992        else
993            continue;
994    }
995
996    :: freeaddrinfo (service_info_list);
997
998    if (m_fd_send == -1)
999    {
1000        Disconnect (NULL);
1001        return eConnectionStatusError;
1002    }
1003
1004    if (error_ptr)
1005        error_ptr->Clear();
1006
1007    m_should_close_fd = true;
1008    return eConnectionStatusSuccess;
1009}
1010
1011#if defined(__MINGW32__) || defined(__MINGW64__)
1012typedef const char * set_socket_option_arg_type;
1013typedef char * get_socket_option_arg_type;
1014#else // #if defined(__MINGW32__) || defined(__MINGW64__)
1015typedef const void * set_socket_option_arg_type;
1016typedef void * get_socket_option_arg_type;
1017#endif // #if defined(__MINGW32__) || defined(__MINGW64__)
1018
1019int
1020ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value)
1021{
1022    get_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value);
1023    socklen_t option_value_size = sizeof(int);
1024	return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size);
1025}
1026
1027int
1028ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value)
1029{
1030    set_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value);
1031	return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value));
1032}
1033
1034bool
1035ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec)
1036{
1037    switch (m_fd_recv_type)
1038    {
1039        case eFDTypeFile:       // Other FD requireing read/write
1040            break;
1041
1042        case eFDTypeSocket:     // Socket requiring send/recv
1043        case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
1044        {
1045            // Check in case timeout for m_fd has already been set to this value
1046            if (timeout_usec == m_socket_timeout_usec)
1047                return true;
1048            //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec);
1049
1050            struct timeval timeout;
1051            if (timeout_usec == UINT32_MAX)
1052            {
1053                timeout.tv_sec = 0;
1054                timeout.tv_usec = 0;
1055            }
1056            else if (timeout_usec == 0)
1057            {
1058                // Sending in zero does an infinite timeout, so set this as low
1059                // as we can go to get an effective zero timeout...
1060                timeout.tv_sec = 0;
1061                timeout.tv_usec = 1;
1062            }
1063            else
1064            {
1065                timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec;
1066                timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec;
1067            }
1068            if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
1069            {
1070                m_socket_timeout_usec = timeout_usec;
1071                return true;
1072            }
1073        }
1074    }
1075    return false;
1076}
1077
1078in_port_t
1079ConnectionFileDescriptor::GetSocketPort (int fd)
1080{
1081    // We bound to port zero, so we need to figure out which port we actually bound to
1082    SocketAddress sock_addr;
1083    socklen_t sock_addr_len = sock_addr.GetMaxLength ();
1084    if (::getsockname (fd, sock_addr, &sock_addr_len) == 0)
1085        return sock_addr.GetPort ();
1086
1087    return 0;
1088}
1089
1090// If the read file descriptor is a socket, then return
1091// the port number that is being used by the socket.
1092in_port_t
1093ConnectionFileDescriptor::GetReadPort () const
1094{
1095    return ConnectionFileDescriptor::GetSocketPort (m_fd_recv);
1096}
1097
1098// If the write file descriptor is a socket, then return
1099// the port number that is being used by the socket.
1100in_port_t
1101ConnectionFileDescriptor::GetWritePort () const
1102{
1103    return ConnectionFileDescriptor::GetSocketPort (m_fd_send);
1104}
1105
1106
1107