Fabcoin Core  0.16.2
P2P Digital Currency
UnixSocketServer.cpp
Go to the documentation of this file.
1 /*
2 This file is part of cpp-ethereum.
3 
4 cpp-ethereum is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8 
9 cpp-ethereum is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #if !defined(_WIN32)
23 
24 #include "UnixSocketServer.h"
25 #include <cstdlib>
26 #include <sys/socket.h>
27 #include <cstdio>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <string>
31 #include <libdevcore/Guards.h>
32 #include <libdevcore/FileSystem.h>
33 
34 // "Mac OS X does not support the flag MSG_NOSIGNAL but we have an equivalent."
35 // See http://lists.apple.com/archives/macnetworkprog/2002/Dec/msg00091.html
36 #if defined(__APPLE__)
37  #if !defined(MSG_NOSIGNAL)
38  #define MSG_NOSIGNAL SO_NOSIGPIPE
39  #endif
40 #endif
41 
42 using namespace std;
43 using namespace jsonrpc;
44 using namespace dev;
45 
46 int const c_pathMaxSize = sizeof(sockaddr_un::sun_path)/sizeof(sockaddr_un::sun_path[0]);
47 
48 string ipcSocketPath()
49 {
50 #ifdef __APPLE__
51  // A bit hacky, but backwards compatible: If we did not change the default data dir,
52  // put the socket in ~/Library/Ethereum, otherwise in the set data dir.
53  string path = getIpcPath();
54  if (path == getDefaultDataDir())
55  return getenv("HOME") + string("/Library/Ethereum");
56  else
57  return path;
58 #else
59  return getIpcPath();
60 #endif
61 }
62 
63 UnixDomainSocketServer::UnixDomainSocketServer(string const& _appId):
64  IpcServerBase(string(getIpcPath() + "/" + _appId + ".ipc").substr(0, c_pathMaxSize))
65 {
66 }
67 
69 {
70  StopListening();
71 }
72 
74 {
75  if (!m_running)
76  {
77  if (access(m_path.c_str(), F_OK) != -1)
78  unlink(m_path.c_str());
79 
80  if (access(m_path.c_str(), F_OK) != -1)
81  return false;
82 
83  m_socket = socket(PF_UNIX, SOCK_STREAM, 0);
84  memset(&(m_address), 0, sizeof(sockaddr_un));
85  m_address.sun_family = AF_UNIX;
86 #ifdef __APPLE__
87  m_address.sun_len = m_path.size() + 1;
88 #endif
89  strncpy(m_address.sun_path, m_path.c_str(), c_pathMaxSize);
90  ::bind(m_socket, reinterpret_cast<sockaddr*>(&m_address), sizeof(sockaddr_un));
91  listen(m_socket, 128);
92  }
94 }
95 
97 {
98  shutdown(m_socket, SHUT_RDWR);
99  close(m_socket);
100  m_socket = -1;
102  {
103  unlink(m_path.c_str());
104  return true;
105  }
106  return false;
107 }
108 
110 {
111  socklen_t addressLen = sizeof(m_address);
112  while (m_running)
113  {
114  int connection = accept(m_socket, (sockaddr*) &(m_address), &addressLen);
115  if (connection > 0)
116  {
118  m_sockets.insert(connection);
119 
120  std::thread handler([this, connection](){ GenerateResponse(connection); });
121  handler.detach();
122  }
123  }
124 }
125 
127 {
128  close(_socket);
129 }
130 
131 
132 size_t UnixDomainSocketServer::Write(int _connection, string const& _data)
133 {
134  int r = send(_connection, _data.data(), _data.size(), MSG_NOSIGNAL);
135  if (r > 0)
136  return r;
137  return 0;
138 }
139 
140 size_t UnixDomainSocketServer::Read(int _connection, void* _data, size_t _size)
141 {
142  int r = read(_connection, _data, _size);
143  if (r > 0)
144  return r;
145  return 0;
146 }
147 
148 #endif
bool(* handler)(HTTPRequest *req, const std::string &strReq)
Definition: rest.cpp:624
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::string getDefaultDataDir(std::string _prefix="ethereum")
void CloseConnection(int _socket) override
#define MSG_NOSIGNAL
Definition: net.cpp:48
std::hash for asio::adress
Definition: Common.h:323
#define DEV_GUARDED(MUTEX)
Simple block guard.
Definition: Guards.h:144
std::string getIpcPath()
Definition: FileSystem.cpp:56
void GenerateResponse(int_connection)
virtual bool StopListening()
size_t Write(int _connection, std::string const &_data) override
virtual bool StartListening()
size_t Read(int _connection, void *_data, size_t _size) override
string ipcSocketPath()
int const c_pathMaxSize
std::unordered_set< int > m_sockets
Definition: IpcServerBase.h:51