14e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 24e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#include "XmlRpcSocket.h" 34e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#include "XmlRpcUtil.h" 44e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 54e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#ifndef MAKEDEPEND 64e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 74e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 84e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <stdio.h> 94e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <winsock2.h> 104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius//# pragma lib(WS2_32.lib) 114e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# define EINPROGRESS WSAEINPROGRESS 134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# define EWOULDBLOCK WSAEWOULDBLOCK 144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# define ETIMEDOUT WSAETIMEDOUT 154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusextern "C" { 174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <unistd.h> 184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <stdio.h> 194e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <sys/types.h> 204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <sys/socket.h> 214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <netinet/in.h> 224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <netdb.h> 234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <errno.h> 244e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <fcntl.h> 254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif // _WINDOWS 274e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif // MAKEDEPEND 294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 314e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piususing namespace XmlRpc; 324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 334e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 344e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 354e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 364e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic void initWinSock() 384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius static bool wsInit = false; 404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius if (! wsInit) 414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius { 424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius WORD wVersionRequested = MAKEWORD( 2, 0 ); 434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius WSADATA wsaData; 444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius WSAStartup(wVersionRequested, &wsaData); 454e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius wsInit = true; 464e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } 474e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 484e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#define initWinSock() 524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 534e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif // _WINDOWS 544e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 554e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 564e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// These errors are not considered fatal for an IO operation; the operation will be re-tried. 574e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic inline bool 584e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusnonFatalError() 594e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 604e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int err = XmlRpcSocket::getError(); 614e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK || err == EINTR); 624e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 634e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 644e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 654e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 664e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusint 674e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::socket() 684e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 694e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius initWinSock(); 704e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (int) ::socket(AF_INET, SOCK_STREAM, 0); 714e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 724e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 734e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 744e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusvoid 754e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::close(int fd) 764e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 774e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius XmlRpcUtil::log(4, "XmlRpcSocket::close: fd %d.", fd); 784e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 794e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius closesocket(fd); 804e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 814e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius ::close(fd); 824e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif // _WINDOWS 834e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 844e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 854e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 864e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 874e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 884e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool 894e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::setNonBlocking(int fd) 904e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 914e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 924e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius unsigned long flag = 1; 934e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (ioctlsocket((SOCKET)fd, FIONBIO, &flag) == 0); 944e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 954e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (fcntl(fd, F_SETFL, O_NONBLOCK) == 0); 964e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif // _WINDOWS 974e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 984e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 994e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1004e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool 1014e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::setReuseAddr(int fd) 1024e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 1034e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius // Allow this port to be re-bound immediately so server re-starts are not delayed 1044e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int sflag = 1; 1054e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&sflag, sizeof(sflag)) == 0); 1064e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 1074e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1084e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1094e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Bind to a specified port 1104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool 1114e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::bind(int fd, int port) 1124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 1134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius struct sockaddr_in saddr; 1144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius memset(&saddr, 0, sizeof(saddr)); 1154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius saddr.sin_family = AF_INET; 1164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius saddr.sin_addr.s_addr = htonl(INADDR_ANY); 1174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius saddr.sin_port = htons((u_short) port); 1184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (::bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == 0); 1194e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 1204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Set socket in listen mode 1234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool 1244e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::listen(int fd, int backlog) 1254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 1264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (::listen(fd, backlog) == 0); 1274e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 1284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusint 1314e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::accept(int fd) 1324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 1334e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius struct sockaddr_in addr; 1344e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 1354e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int 1364e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 1374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius socklen_t 1384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif 1394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius addrlen = sizeof(addr); 1404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return (int) ::accept(fd, (struct sockaddr*)&addr, &addrlen); 1424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 1434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1454e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1464e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Connect a socket to a server (from a client) 1474e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool 1484e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::connect(int fd, std::string& host, int port) 1494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 1504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius struct sockaddr_in saddr; 1514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius memset(&saddr, 0, sizeof(saddr)); 1524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius saddr.sin_family = AF_INET; 1534e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1544e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius struct hostent *hp = gethostbyname(host.c_str()); 1554e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius if (hp == 0) return false; 1564e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1574e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius saddr.sin_family = hp->h_addrtype; 1584e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length); 1594e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius saddr.sin_port = htons((u_short) port); 1604e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1614e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius // For asynch operation, this will return EWOULDBLOCK (windows) or 1624e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius // EINPROGRESS (linux) and we just need to wait for the socket to be writable... 1634e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int result = ::connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); 1644e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return result == 0 || nonFatalError(); 1654e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 1664e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1674e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1684e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1694e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Read available text from the specified socket. Returns false on error. 1704e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool 1714e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::nbRead(int fd, std::string& s, bool *eof) 1724e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 1734e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius const int READ_SIZE = 4096; // Number of bytes to attempt to read at a time 1744e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius char readBuf[READ_SIZE]; 1754e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1764e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius bool wouldBlock = false; 1774e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius *eof = false; 1784e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1794e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius while ( ! wouldBlock && ! *eof) { 1804e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 1814e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int n = recv(fd, readBuf, READ_SIZE-1, 0); 1824e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 1834e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int n = read(fd, readBuf, READ_SIZE-1); 1844e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif 1854e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius XmlRpcUtil::log(5, "XmlRpcSocket::nbRead: read/recv returned %d.", n); 1864e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 1874e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius if (n > 0) { 1884e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius readBuf[n] = 0; 1894e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius s.append(readBuf, n); 1904e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } else if (n == 0) { 1914e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius *eof = true; 1924e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } else if (nonFatalError()) { 1934e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius wouldBlock = true; 1944e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } else { 1954e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return false; // Error 1964e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } 1974e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } 1984e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return true; 1994e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 2004e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2014e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2024e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Write text to the specified socket. Returns false on error. 2034e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool 2044e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::nbWrite(int fd, std::string& s, int *bytesSoFar) 2054e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 2064e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int nToWrite = int(s.length()) - *bytesSoFar; 2074e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius char *sp = const_cast<char*>(s.c_str()) + *bytesSoFar; 2084e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius bool wouldBlock = false; 2094e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius while ( nToWrite > 0 && ! wouldBlock ) { 2114e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 2124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int n = send(fd, sp, nToWrite, 0); 2134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 2144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius int n = write(fd, sp, nToWrite); 2154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif 2164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius XmlRpcUtil::log(5, "XmlRpcSocket::nbWrite: send/write returned %d.", n); 2174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius if (n > 0) { 2194e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius sp += n; 2204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius *bytesSoFar += n; 2214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius nToWrite -= n; 2224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } else if (nonFatalError()) { 2234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius wouldBlock = true; 2244e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } else { 2254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return false; // Error 2264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } 2274e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius } 2284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return true; 2294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 2304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2314e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Returns last errno 2334e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusint 2344e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::getError() 2354e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 2364e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_WINDOWS) 2374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return WSAGetLastError(); 2384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else 2394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return errno; 2404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif 2414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 2424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Returns message corresponding to last errno 2454e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstd::string 2464e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::getErrorMsg() 2474e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 2484e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return getErrorMsg(getError()); 2494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 2504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Returns message corresponding to errno... well, it should anyway 2524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstd::string 2534e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcSocket::getErrorMsg(int error) 2544e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{ 2554e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius char err[60]; 2564e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius snprintf(err,sizeof(err),"error %d", error); 2574e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius return std::string(err); 2584e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} 2594e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 2604e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius 261