Commit 77d957c9 authored by hrchilds's avatar hrchilds
Browse files

Update from May 12, 2006

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@666 18c085ea-50e0-402c-830e-de6fd14e8384
parent 2540c0ee
#include <errno.h>
#if defined(_WIN32)
#include <winsock2.h>
#include <windows.h>
#include <win32commhelpers.h>
#else
#include <netdb.h>
#include <netinet/in.h>
......@@ -20,6 +19,7 @@
#include <CouldNotConnectException.h>
#include <IncompatibleVersionException.h>
// ****************************************************************************
// Method: ParentProcess::ParentProcess
//
......@@ -88,6 +88,9 @@ ParentProcess::ParentProcess() : version(VERSION), localUserName()
// Brad Whitlock, Tue Mar 19 16:05:17 PST 2002
// Made it work on Windows.
//
// Brad Whitlock, Fri May 12 11:49:43 PDT 2006
// We now copy the hostent on Windows, free it here.
//
// ****************************************************************************
ParentProcess::~ParentProcess()
......@@ -131,6 +134,12 @@ ParentProcess::~ParentProcess()
writeConnections = 0;
nWriteConnections = 0;
}
#if defined(_WIN32)
// On Windows, we make a copy. Free it now.
if(hostInfo != NULL)
FreeHostent((struct hostent *)hostInfo);
#endif
}
// ****************************************************************************
......@@ -221,7 +230,7 @@ ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
// Log the arguments.
debug5 << mName << "Called with (numRead=" << numRead
<< ", numWrite=, " << numWrite
<< ", numWrite=" << numWrite
<< ", argc=" << *argc
<< ", argv={";
for (i = 0; i < *argc ; ++i)
......@@ -568,6 +577,9 @@ ParentProcess::GetWriteConnection(int i) const
// Brad Whitlock, Tue Jan 17 14:37:35 PST 2006
// Added debug logging.
//
// Brad Whitlock, Fri May 12 11:50:15 PDT 2006
// Added more extensive debug logging for the Windows platform.
//
// ****************************************************************************
int
......@@ -594,31 +606,50 @@ ParentProcess::GetClientSocketDescriptor(int port)
// Create a socket.
//
debug5 << mName << "Creating a socket" << endl;
#if defined(_WIN32)
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
if (s == INVALID_SOCKET)
{
LogWindowsSocketError(mName, "socket");
return -1;
}
// Disable the Nagle algorithm
debug5 << mName << "Setting socket options" << endl;
int opt = 1;
#if defined(_WIN32)
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&opt, sizeof(int));
#else
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
#endif
if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&opt, sizeof(int))
== SOCKET_ERROR)
{
LogWindowsSocketError(mName, "setsockopt");
}
debug5 << mName << "Calling connect" << endl;
if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0)
{
LogWindowsSocketError(mName, "connect");
debug5 << mName << "Could not connect!" << endl;
#if defined(_WIN32)
closesocket(s);
return -1;
}
#else
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
return -1;
}
// Disable the Nagle algorithm
debug5 << mName << "Setting socket options" << endl;
int opt = 1;
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
debug5 << mName << "Calling connect" << endl;
if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0)
{
debug5 << mName << "Could not connect!" << endl;
close(s);
#endif
return -1;
}
#endif
debug5 << mName << "Connected socket" << endl;
......@@ -637,16 +668,27 @@ ParentProcess::GetClientSocketDescriptor(int port)
// Creation: Fri Jul 21 15:24:10 PST 2000
//
// Modifications:
// Brad Whitlock, Fri May 12 11:50:15 PDT 2006
// Added more extensive debug logging for the Windows platform.
//
// ****************************************************************************
void
ParentProcess::GetHostInfo()
{
debug5 << "ParentProcess::GetHostInfo: Calling gethostbyname(\""
const char *mName = "ParentProcess::GetHostInfo: ";
debug5 << mName << "Calling gethostbyname(\""
<< hostName.c_str() << "\")\n";
#if defined(_WIN32)
// Create a copy of the hostent struct in case other WinSock
// functions want to modify it.
hostInfo = (void *)CopyHostent(gethostbyname(hostName.c_str()));
if(hostInfo == NULL)
LogWindowsSocketError(mName, "gethostbyname");
#else
hostInfo = (void *)gethostbyname(hostName.c_str());
#endif
}
// ****************************************************************************
......
......@@ -4,8 +4,7 @@
#if defined(_WIN32)
#include <process.h>
#include <winsock2.h>
#include <windows.h>
#include <win32commhelpers.h>
#else
#include <netinet/in.h>
#include <netinet/tcp.h>
......@@ -469,6 +468,9 @@ RemoteProcess::GetProcessId() const
// Brad Whitlock, Tue Jan 17 13:37:17 PST 2006
// Added debug logging.
//
// Brad Whitlock, Fri May 12 11:56:59 PDT 2006
// Added more Windows error logging.
//
// ****************************************************************************
bool
......@@ -484,6 +486,9 @@ RemoteProcess::GetSocketAndPort()
{
// Cannot open a socket.
debug5 << mName << "Can't open a socket." << endl;
#if defined(_WIN32)
LogWindowsSocketError(mName, "socket");
#endif
return false;
}
debug5 << mName << "Opened listen socket: " << listenSocketNum << endl;
......@@ -505,12 +510,16 @@ RemoteProcess::GetSocketAndPort()
if (bind(listenSocketNum, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
listenPortNum++;
#if defined(_WIN32)
LogWindowsSocketError(mName, "bind");
#endif
}
else
{
portFound = true;
}
}
if (!portFound)
{
// Cannot find unused port.
......@@ -668,7 +677,11 @@ RemoteProcess::AcceptSocket()
// Disable Nagle algorithm.
#if defined(_WIN32)
setsockopt(desc, IPPROTO_TCP, TCP_NODELAY, (const char FAR*)&opt, sizeof(int));
if(setsockopt(desc, IPPROTO_TCP, TCP_NODELAY, (const char FAR*)&opt, sizeof(int))
== SOCKET_ERROR)
{
LogWindowsSocketError(mName, "setsockopt");
}
#else
setsockopt(desc, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
#endif
......@@ -697,6 +710,9 @@ RemoteProcess::AcceptSocket()
// Brad Whitlock, Tue Jan 17 13:41:47 PST 2006
// Added debug info.
//
// Brad Whitlock, Fri May 12 12:02:10 PDT 2006
// Added more debug info for Windows.
//
// ****************************************************************************
int
......@@ -716,6 +732,10 @@ RemoteProcess::SingleThreadedAcceptSocket()
len = sizeof(struct sockaddr);
debug5 << mName << "waiting for accept() to return" << endl;
desc = accept(listenSocketNum, (struct sockaddr *)&sin, &len);
#if defined(_WIN32)
if(desc == INVALID_SOCKET)
LogWindowsSocketError(mName, "accept");
#endif
}
while (desc == -1 && errno == EINTR && childDied[GetProcessId()] == false);
......@@ -743,6 +763,9 @@ RemoteProcess::SingleThreadedAcceptSocket()
// I put a loop around the accept function call so that if we catch a
// signal during the accept, we have an opportunity to try it again.
//
// Brad Whitlock, Fri May 12 12:02:38 PDT 2006
// Log Windows error messages.
//
// ****************************************************************************
#if defined(WIN32)
......@@ -771,6 +794,10 @@ static void *threaded_accept_callback(void *data)
#endif
len = sizeof(struct sockaddr);
desc = accept(cb->listenSocketNum, (struct sockaddr *)cb->sin, &len);
#if defined(_WIN32)
if(desc == INVALID_SOCKET)
LogWindowsSocketError("threaded_accept_callback", "accept");
#endif
} while(desc == -1 && errno == EINTR && childDied[cb->pid] == false);
// Set the results into the callback struct that the other thread is polling.
......@@ -1192,6 +1219,9 @@ RemoteProcess::StartMakingConnection(const std::string &rHost, int numRead,
bool remote = (remoteHost != std::string("localhost"));
if(remote && (gethostbyname(remoteHost.c_str()) == NULL))
{
#if defined(_WIN32)
LogWindowsSocketError(mName, "gethostbyname,1");
#endif
EXCEPTION1(BadHostException, remoteHost);
}
......@@ -1203,6 +1233,9 @@ RemoteProcess::StartMakingConnection(const std::string &rHost, int numRead,
char localHostStr[256];
if (gethostname(localHostStr, 256) == -1)
{
#if defined(_WIN32)
LogWindowsSocketError(mName, "gethostname");
#endif
// Couldn't get the hostname, it's probably invalid so
// throw a BadHostException.
EXCEPTION1(BadHostException, localHostStr);
......@@ -1213,6 +1246,9 @@ RemoteProcess::StartMakingConnection(const std::string &rHost, int numRead,
struct hostent *localHostEnt = gethostbyname(localHostStr);
if (localHostEnt == NULL)
{
#if defined(_WIN32)
LogWindowsSocketError(mName, "gethostbyname,2");
#endif
// Couldn't get the full host entry; it's probably invalid so
// throw a BadHostException.
EXCEPTION1(BadHostException, localHostStr);
......@@ -1244,6 +1280,10 @@ RemoteProcess::StartMakingConnection(const std::string &rHost, int numRead,
debug5 << mName << "gethostbyaddr returned: " << localHost.c_str()
<< endl;
}
#if defined(_WIN32)
else
LogWindowsSocketError(mName, "gethostbyaddr");
#endif
}
}
}
......@@ -1285,8 +1325,12 @@ RemoteProcess::StartMakingConnection(const std::string &rHost, int numRead,
// Start listening for connections.
//
debug5 << mName << "Start listening for connections." << endl;
#if defined(_WIN32)
if(listen(listenSocketNum, 5) == SOCKET_ERROR)
LogWindowsSocketError(mName, "listen");
#else
listen(listenSocketNum, 5);
#endif
return true;
}
......
#include <win32commhelpers.h>
#include <DebugStream.h>
#if defined(_WIN32)
static void
CopyHostentString(char **dest, char *src, const char *name, const char *mName)
{
if(src == NULL)
{
*dest = NULL;
debug5 << mName << name << " = NULL" << endl;
}
else
{
int len = strlen(src)+1;
*dest = (char*)malloc(len);
memset(*dest, 0, len);
strcpy(*dest, src);
debug5 << mName << name << " = " << src << endl;
}
}
static void
CopyHostentStringList(char ***destp, char **src, const char *name, const char *mName)
{
if(src == NULL)
{
debug5 << mName << name << " = NULL" << endl;
*destp = NULL;
return;
}
// Count the number of items in the list.
int numEntries = 0;
for(char **ptr = src; *ptr != NULL; ++ptr)
++numEntries;
char **dest = (char **)malloc(numEntries + 1);
debug5 << mName << name << " = {" << endl;
for(int i = 0; src[i] != NULL; ++i)
CopyHostentString(&dest[i], src[i], "", mName);
dest[numEntries] = NULL;
debug5 << mName << "NULL" << endl;
debug5 << mName << "}" << endl;
*destp = dest;
}
// ****************************************************************************
// Method: CopyHostent
//
// Purpose:
// Copies a hostent structure and returns a pointer to the new one.
//
// Arguments:
// h : The hostent structure to copy.
//
// Returns: A pointer to a new hostent structure.
//
// Note:
//
// Programmer: Brad Whitlock
// Creation: Fri May 12 12:15:26 PDT 2006
//
// Modifications:
//
// ****************************************************************************
struct hostent *
CopyHostent(struct hostent *h)
{
const char *mName = "CopyHostent: ";
if(h == NULL)
{
debug5 << mName << "Returning NULL. This means gethostbyname failed" << endl;
return NULL;
}
struct hostent *h2 = (struct hostent *)malloc(sizeof(struct hostent));
CopyHostentString(&h2->h_name, h->h_name, "hostent->h_name", mName);
CopyHostentStringList(&h2->h_aliases, (char **)h->h_aliases, "hostent->h_aliases", mName);
h2->h_addrtype = h->h_addrtype;
debug5 << mName << "hostent->h_addrtype = " << h2->h_addrtype << endl;
h2->h_length = h->h_length;
debug5 << mName << "hostent->h_length = " << h2->h_length << endl;
CopyHostentStringList(&h2->h_addr_list, (char **)h->h_addr_list, "hostent->h_addr_list", mName);
return h2;
}
// ****************************************************************************
// Method: FreeHostent
//
// Purpose:
// Frees a hostent structure.
//
// Arguments:
// h : The hostent structure to free.
//
// Programmer: Brad Whitlock
// Creation: Fri May 12 12:16:08 PDT 2006
//
// Modifications:
//
// ****************************************************************************
void
FreeHostent(struct hostent *h)
{
if(h->h_name != NULL)
free(h->h_name);
if(h->h_aliases != NULL)
{
for(int i = 0; h->h_aliases[i] != NULL; ++i)
free(h->h_aliases[i]);
free(h->h_aliases);
}
if(h->h_addr_list != NULL)
{
for(int i = 0; h->h_addr_list[i] != NULL; ++i)
free(h->h_addr_list[i]);
free(h->h_addr_list);
}
free(h);
}
// ****************************************************************************
// Method: LogWindowsSocketError
//
// Purpose:
// Writes Windows socket error messages to the debug5 log file.
//
// Arguments:
// mName : The method that called networking functions.
// fName : The name of the networking function that failed.
//
// Programmer: Brad Whitlock
// Creation: Fri May 12 12:16:37 PDT 2006
//
// Modifications:
//
// ****************************************************************************
void
LogWindowsSocketError(const char *mName, const char *fName)
{
debug5 << mName << "Call to \"" << fName << "\" failed:";
switch(WSAGetLastError())
{
case WSANOTINITIALISED:
debug5 << "WSAENOTINITIALISED: WSAStartup() must be called before using this API.";
break;
case WSAENETDOWN:
debug5 << "WSAENETDOWN: The network subsystem or the associated service provider has failed.";
break;
case WSAEAFNOSUPPORT:
debug5 << "WSAEAFNOSUPPORT: The specified address family is not supported.";
break;
case WSAEINPROGRESS:
debug5 << "WSAEINPROGRESS: A blocking Winsock 1.1 call is in progress, or the service provider is still processing a callback function.";
break;
case WSAEFAULT:
debug5 << "WSAEFAULT: See documentation for: " << fName;
break;
case WSAEINTR:
debug5 << "WSAEINTR: A blocking WinSock 1.1 call was canceled via WSACancelBlockingCall.";
break;
case WSAEMFILE:
debug5 << "WSAEMFILE: No more socket descriptors are available.";
break;
case WSAENOBUFS:
debug5 << "WSAENOBUFS: No buffer space is available. The socket cannot be created.";
break;
case WSAEPROTONOSUPPORT:
debug5 << "WSAEPROTONOSUPPORT: The specified protocol is not supported.";
break;
case WSAEPROTOTYPE:
debug5 << "WSAEPROTOTYPE: The specified protocol is the wrong type for this socket.";
break;
case WSAESOCKTNOSUPPORT:
debug5 << "WSAESOCKTNOSUPPORT: The specified socket type is not supported in this address family.";
break;
case WSAHOST_NOT_FOUND:
debug5 << "WSAHOST_NOT_FOUND: Authoratiative Answer Host not found.";
break;
case WSATRY_AGAIN:
debug5 << "WSATRY_AGAIN: Non-Authoratative Host not found, or server failure.";
break;
case WSANO_RECOVERY:
debug5 << "WSANO_RECOVERY: Non-recoverable error occurred.";
break;
case WSANO_DATA:
debug5 << "WSANO_DATA: Valid name, no data record of requested type.";
break;
case WSAEINVAL:
debug5 << "WSAEINVAL: See documentation for: " << fName;
break;
case WSAENETRESET:
debug5 << "WSAENETRESET: The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress.";
break;
case WSAENOPROTOOPT:
debug5 << "WSAENOPROTOOPT: The option is unknown or unsupported for the specified provider or socket.";
break;
case WSAENOTCONN:
debug5 << "WSAENOTCONN: Connection has been reset when SO_KEEPALIVE is set.";
break;
case WSAENOTSOCK:
debug5 << "WSAENOTSOCK: The descriptor is not a socket.";
break;
case WSAEADDRINUSE:
debug5 << "WSAEADDRINUSE: The socket's local address space is already in use and the socket was not marked to allow address reuse.";
break;
case WSAEALREADY:
debug5 << "WSAEALREADY: A non-blocking connect() call is in progress or the service provider is still processing a callback function.";
break;
case WSAEADDRNOTAVAIL:
debug5 << "WSAADDRNOTAVAIL: The remote address is not valid (e.g. ADDR_ANY).";
break;
case WSAECONNREFUSED:
debug5 << "WSAECONNREFUSED: The attempt to connect was forcefully rejected.";
break;
case WSAEISCONN:
debug5 << "WSAEISCONN: The socket is already connected.";
break;
case WSAENETUNREACH:
debug5 << "WSAENETUNREACH: The network can't be reached from this host at this time.";
break;
case WSAETIMEDOUT:
debug5 << "WSAETIMEDOUT: Attempt to connect timed out without establishing a connection.";
break;
case WSAEWOULDBLOCK:
debug5 << "WSAEWOULDBLOCK: The socket it marked as non-blocking and the connection cannot be completed immediately.";
break;
case WSAEACCES:
debug5 << "WSAEACCES: Attempt to connect datagram socket to broadcast address failed.";
break;
case WSAEOPNOTSUPP:
debug5 << "WSAENOTSUPP: The referenced socket is not of a type that supports listen().";
break;
default:
debug5 << "WSA error: " << WSAGetLastError();
}
debug5 << endl;
}
#endif
#ifndef WIN32_COMM_HELPERS_H
#define WIN32_COMM_HELPERS_H
#if defined(_WIN32)
#include <winsock2.h>
#include <windows.h>
struct hostent *CopyHostent(struct hostent *h);
void FreeHostent(struct hostent *h);
void LogWindowsSocketError(const char *mName, const char *fName);
#endif
#endif
......@@ -6,21 +6,21 @@
//
static const char *Severity_strings[] = {
"Error", "Warning", "Message"
};
"Error", "Warning", "Message",
"ErrorClear"};
std::string
MessageAttributes::Severity_ToString(MessageAttributes::Severity t)
{
int index = int(t);
if(index < 0 || index >= 3) index = 0;
if(index < 0 || index >= 4) index = 0;
return Severity_strings[index];
}
std::string
MessageAttributes::Severity_ToString(int t)
{
int index = (t < 0 || t >= 3) ? 0 : t;
int index = (t < 0 || t >= 4) ? 0 : t;
return Severity_strings[index];
}
......@@ -28,7 +28,7 @@ bool
MessageAttributes::Severity_FromString(const std::string &s, MessageAttributes::Severity &val)
{
val = MessageAttributes::Error;
for(int i = 0; i < 3; ++i)
for(int i = 0; i < 4; ++i)
{
if(s == Severity_strings[i])
{
......@@ -48,7 +48,7 @@ MessageAttributes::Severity_FromString(const std::string &s, MessageAttributes::
// Note: Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation: Thu Dec 18 11:24:16 PDT 2003
// Creation: Thu May 11 14:56:29 PST 2006
//
// Modifications:
//
......@@ -69,7 +69,7 @@ MessageAttributes::MessageAttributes() : AttributeSubject("si")
// Note: Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation: Thu Dec 18 11:24:16 PDT 2003
// Creation: Thu May 11 14:56:29 PST 2006
//
// Modifications:
//
......@@ -92,7 +92,7 @@ MessageAttributes::MessageAttributes(const MessageAttributes &obj) : AttributeSu
// Note: Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation: Thu Dec 18 11:24:16 PDT 2003
// Creation: Thu May 11 14:56:29 PST 2006