~ubuntu-branches/ubuntu/wily/flrig/wily

« back to all changes in this revision

Viewing changes to src/xmlrpcpp/XmlRpcSocket.cpp

  • Committer: Package Import Robot
  • Author(s): Kamal Mostafa
  • Date: 2014-06-07 11:28:52 UTC
  • Revision ID: package-import@ubuntu.com-20140607112852-v4d5tb1m3h3vi0dl
Tags: upstream-1.3.15
ImportĀ upstreamĀ versionĀ 1.3.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// XmlRpc++ Copyright (c) 2002-2008 by Chris Morley
 
3
//
 
4
 
 
5
#include "XmlRpcSocket.h"
 
6
#include "XmlRpcUtil.h"
 
7
 
 
8
 
 
9
#if defined(_WINDOWS)
 
10
# include <stdio.h>
 
11
# include <winsock2.h>
 
12
//# pragma lib(WS2_32.lib)
 
13
 
 
14
# define EINPROGRESS    WSAEINPROGRESS
 
15
# define EWOULDBLOCK    WSAEWOULDBLOCK
 
16
# define ETIMEDOUT          WSAETIMEDOUT
 
17
 
 
18
typedef int socklen_t;
 
19
 
 
20
#else
 
21
extern "C" {
 
22
# include <unistd.h>
 
23
# include <stdio.h>
 
24
# include <string.h>
 
25
# include <sys/types.h>
 
26
# include <sys/socket.h>
 
27
# include <netinet/in.h>
 
28
# include <netdb.h>
 
29
# include <errno.h>
 
30
# include <fcntl.h>
 
31
# include <signal.h>
 
32
}
 
33
#endif  // _WINDOWS
 
34
 
 
35
 
 
36
using namespace XmlRpc;
 
37
 
 
38
 
 
39
// One-time initializations
 
40
static bool initialized = false;
 
41
  
 
42
 
 
43
static void initialize()
 
44
{
 
45
    initialized = true;
 
46
 
 
47
#if defined(_WINDOWS)
 
48
    {
 
49
        WORD wVersionRequested = MAKEWORD( 2, 0 );
 
50
        WSADATA wsaData;
 
51
        WSAStartup(wVersionRequested, &wsaData);
 
52
    }
 
53
#else
 
54
    {
 
55
        // Ignore SIGPIPE
 
56
        (void) signal(SIGPIPE, SIG_IGN);
 
57
    }
 
58
#endif // _WINDOWS
 
59
}
 
60
 
 
61
 
 
62
 
 
63
// These errors are not considered fatal for an IO operation; the operation will be re-tried.
 
64
bool
 
65
XmlRpcSocket::nonFatalError()
 
66
{
 
67
  int err = XmlRpcSocket::getError();
 
68
  return (err == EINPROGRESS ||
 
69
#if defined(EAGAIN)
 
70
          err == EAGAIN ||
 
71
#endif
 
72
#if defined(EINTR)
 
73
          err == EINTR ||
 
74
#endif
 
75
          err == EWOULDBLOCK);
 
76
}
 
77
 
 
78
 
 
79
XmlRpcSocket::Socket
 
80
XmlRpcSocket::socket()
 
81
{
 
82
  if ( ! initialized) initialize();
 
83
  return ::socket(AF_INET, SOCK_STREAM, 0);
 
84
}
 
85
 
 
86
 
 
87
void
 
88
XmlRpcSocket::close(XmlRpcSocket::Socket fd)
 
89
{
 
90
  XmlRpcUtil::log(4, "XmlRpcSocket::close: fd %d.", fd);
 
91
#if defined(_WINDOWS)
 
92
  closesocket(fd);
 
93
#else
 
94
  ::close(fd);
 
95
#endif // _WINDOWS
 
96
}
 
97
 
 
98
 
 
99
 
 
100
 
 
101
bool
 
102
XmlRpcSocket::setNonBlocking(XmlRpcSocket::Socket fd)
 
103
{
 
104
#if defined(_WINDOWS)
 
105
  unsigned long flag = 1;
 
106
  return (ioctlsocket(fd, FIONBIO, &flag) == 0);
 
107
#else
 
108
  return (fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
 
109
#endif // _WINDOWS
 
110
}
 
111
 
 
112
 
 
113
bool
 
114
XmlRpcSocket::setReuseAddr(XmlRpcSocket::Socket fd)
 
115
{
 
116
  // Allow this port to be re-bound immediately so server re-starts are not delayed
 
117
  int sflag = 1;
 
118
  return (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&sflag, sizeof(sflag)) == 0);
 
119
}
 
120
 
 
121
 
 
122
// Bind to a specified port
 
123
bool 
 
124
XmlRpcSocket::bind(XmlRpcSocket::Socket fd, int port)
 
125
{
 
126
  struct sockaddr_in saddr;
 
127
  memset(&saddr, 0, sizeof(saddr));
 
128
  saddr.sin_family = AF_INET;
 
129
  saddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
130
  saddr.sin_port = htons((u_short) port);
 
131
  return (::bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == 0);
 
132
}
 
133
 
 
134
 
 
135
// Set socket in listen mode
 
136
bool 
 
137
XmlRpcSocket::listen(XmlRpcSocket::Socket fd, int backlog)
 
138
{
 
139
  return (::listen(fd, backlog) == 0);
 
140
}
 
141
 
 
142
 
 
143
XmlRpcSocket::Socket
 
144
XmlRpcSocket::accept(XmlRpcSocket::Socket fd)
 
145
{
 
146
  struct sockaddr_in addr;
 
147
  socklen_t addrlen = sizeof(addr);
 
148
 
 
149
  return ::accept(fd, (struct sockaddr*)&addr, &addrlen);
 
150
}
 
151
 
 
152
 
 
153
    
 
154
// Connect a socket to a server (from a client)
 
155
bool
 
156
XmlRpcSocket::connect(XmlRpcSocket::Socket fd, std::string& host, int port)
 
157
{
 
158
  struct sockaddr_in saddr;
 
159
  memset(&saddr, 0, sizeof(saddr));
 
160
  saddr.sin_family = AF_INET;
 
161
 
 
162
  struct hostent *hp = gethostbyname(host.c_str());
 
163
  if (hp == 0) return false;
 
164
 
 
165
  saddr.sin_family = hp->h_addrtype;
 
166
  memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
 
167
  saddr.sin_port = htons((u_short) port);
 
168
 
 
169
  // For asynch operation, this will return EWOULDBLOCK (windows) or
 
170
  // EINPROGRESS (linux) and we just need to wait for the socket to be writable...
 
171
  int result = ::connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
 
172
  return result == 0 || nonFatalError();
 
173
}
 
174
 
 
175
 
 
176
 
 
177
// Get the port of a bound socket
 
178
int
 
179
XmlRpcSocket::getPort(XmlRpcSocket::Socket socket)
 
180
{
 
181
  struct sockaddr_in saddr;
 
182
  socklen_t saddr_len = sizeof(saddr);
 
183
  int port;
 
184
 
 
185
  int result = ::getsockname(socket, (sockaddr*) &saddr, &saddr_len);
 
186
 
 
187
  if (result != 0) {
 
188
    port = -1;
 
189
  } else {
 
190
    port = ntohs(saddr.sin_port);
 
191
  }
 
192
  return port;
 
193
}
 
194
 
 
195
 
 
196
// Returns last errno
 
197
int 
 
198
XmlRpcSocket::getError()
 
199
{
 
200
#if defined(_WINDOWS)
 
201
  return WSAGetLastError();
 
202
#else
 
203
  return errno;
 
204
#endif
 
205
}
 
206
 
 
207
 
 
208
// Returns message corresponding to last errno
 
209
std::string 
 
210
XmlRpcSocket::getErrorMsg()
 
211
{
 
212
  return getErrorMsg(getError());
 
213
}
 
214
 
 
215
// Returns message corresponding to errno... well, it should anyway
 
216
std::string 
 
217
XmlRpcSocket::getErrorMsg(int error)
 
218
{
 
219
  char err[60];
 
220
  snprintf(err,sizeof(err),"error %d", error);
 
221
  return std::string(err);
 
222
}
 
223
 
 
224