1 //===-- ConnectionFileDescriptorPosix.h -------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_HOST_POSIX_CONNECTIONFILEDESCRIPTORPOSIX_H
10 #define LLDB_HOST_POSIX_CONNECTIONFILEDESCRIPTORPOSIX_H
11 
12 #include <atomic>
13 #include <memory>
14 #include <mutex>
15 
16 #include "lldb/lldb-forward.h"
17 
18 #include "lldb/Host/Pipe.h"
19 #include "lldb/Utility/Connection.h"
20 #include "lldb/Utility/IOObject.h"
21 #include "lldb/Utility/Predicate.h"
22 
23 namespace lldb_private {
24 
25 class Status;
26 class Socket;
27 class SocketAddress;
28 
29 class ConnectionFileDescriptor : public Connection {
30 public:
31   static const char *LISTEN_SCHEME;
32   static const char *ACCEPT_SCHEME;
33   static const char *UNIX_ACCEPT_SCHEME;
34   static const char *CONNECT_SCHEME;
35   static const char *TCP_CONNECT_SCHEME;
36   static const char *UDP_SCHEME;
37   static const char *UNIX_CONNECT_SCHEME;
38   static const char *UNIX_ABSTRACT_CONNECT_SCHEME;
39   static const char *FD_SCHEME;
40   static const char *FILE_SCHEME;
41 
42   ConnectionFileDescriptor(bool child_processes_inherit = false);
43 
44   ConnectionFileDescriptor(int fd, bool owns_fd);
45 
46   ConnectionFileDescriptor(Socket *socket);
47 
48   ~ConnectionFileDescriptor() override;
49 
50   bool IsConnected() const override;
51 
52   lldb::ConnectionStatus Connect(llvm::StringRef s, Status *error_ptr) override;
53 
54   lldb::ConnectionStatus Disconnect(Status *error_ptr) override;
55 
56   size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout,
57               lldb::ConnectionStatus &status, Status *error_ptr) override;
58 
59   size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status,
60                Status *error_ptr) override;
61 
62   std::string GetURI() override;
63 
64   lldb::ConnectionStatus BytesAvailable(const Timeout<std::micro> &timeout,
65                                         Status *error_ptr);
66 
67   bool InterruptRead() override;
68 
69   lldb::IOObjectSP GetReadObject() override { return m_read_sp; }
70 
71   uint16_t GetListeningPort(const Timeout<std::micro> &timeout);
72 
73   bool GetChildProcessesInherit() const;
74   void SetChildProcessesInherit(bool child_processes_inherit);
75 
76 protected:
77   void OpenCommandPipe();
78 
79   void CloseCommandPipe();
80 
81   lldb::ConnectionStatus SocketListenAndAccept(llvm::StringRef host_and_port,
82                                                Status *error_ptr);
83 
84   lldb::ConnectionStatus ConnectTCP(llvm::StringRef host_and_port,
85                                     Status *error_ptr);
86 
87   lldb::ConnectionStatus ConnectUDP(llvm::StringRef args, Status *error_ptr);
88 
89   lldb::ConnectionStatus NamedSocketConnect(llvm::StringRef socket_name,
90                                             Status *error_ptr);
91 
92   lldb::ConnectionStatus NamedSocketAccept(llvm::StringRef socket_name,
93                                            Status *error_ptr);
94 
95   lldb::ConnectionStatus UnixAbstractSocketConnect(llvm::StringRef socket_name,
96                                                    Status *error_ptr);
97 
98   lldb::IOObjectSP m_read_sp;
99   lldb::IOObjectSP m_write_sp;
100 
101   Predicate<uint16_t>
102       m_port_predicate; // Used when binding to port zero to wait for the thread
103                         // that creates the socket, binds and listens to
104                         // resolve the port number.
105 
106   Pipe m_pipe;
107   std::recursive_mutex m_mutex;
108   std::atomic<bool> m_shutting_down; // This marks that we are shutting down so
109                                      // if we get woken up from
110   // BytesAvailable to disconnect, we won't try to read again.
111   bool m_waiting_for_accept;
112   bool m_child_processes_inherit;
113 
114   std::string m_uri;
115 
116 private:
117   void InitializeSocket(Socket *socket);
118 
119   ConnectionFileDescriptor(const ConnectionFileDescriptor &) = delete;
120   const ConnectionFileDescriptor &
121   operator=(const ConnectionFileDescriptor &) = delete;
122 };
123 
124 } // namespace lldb_private
125 
126 #endif // LLDB_HOST_POSIX_CONNECTIONFILEDESCRIPTORPOSIX_H
127