WvStreams
wverror.cc
1 /*
2  * Worldvisions Weaver Software:
3  * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4  *
5  * A class for managing error numbers and strings. See wverror.h.
6  */
7 #include "wverror.h"
8 #include <assert.h>
9 
10 #ifdef _WIN32
11 #include "windows.h"
12 
13 struct WvErrMap {
14  int num;
15  const char *str;
16 };
17 
18 static WvErrMap wverrmap[] = {
19  { WSAEINTR, "Interrupted" },
20  { WSAEBADF, "Bad file descriptor" },
21  { WSAEACCES, "Access denied" },
22  { WSAEFAULT, "Bad address" },
23  { WSAEINVAL, "Invalid argument" },
24  { WSAEMFILE, "Too many open files" },
25  { WSAEWOULDBLOCK, "Operation would block" },
26  { WSAEINPROGRESS, "Operation now in progress" },
27  { WSAEALREADY, "Operation already in progress" },
28  { WSAENOTSOCK, "Socket operation on non-socket" },
29  { WSAEDESTADDRREQ, "Destination address required" },
30  { WSAEMSGSIZE, "Message too long" },
31  { WSAEPROTOTYPE, "Protocol wrong type for socket" },
32  { WSAENOPROTOOPT, "Protocol not available" },
33  { WSAEPROTONOSUPPORT, "Protocol not supported" },
34  { WSAESOCKTNOSUPPORT, "Socket type not supported" },
35  { WSAEOPNOTSUPP, "Operation not supported on transport endpoint" },
36  { WSAEPFNOSUPPORT, "Protocol family not supported" },
37  { WSAEAFNOSUPPORT, "Address family not supported by protocol" },
38  { WSAEADDRINUSE, "Address already in use" },
39  { WSAEADDRNOTAVAIL, "Cannot assign requested address" },
40  { WSAENETDOWN, "Network is down" },
41  { WSAENETUNREACH, "Network is unreachable" },
42  { WSAENETRESET, "Network dropped connection because of reset" },
43  { WSAECONNABORTED, "Software caused connection abort" },
44  { WSAECONNRESET, "Connection reset by peer" },
45  { WSAENOBUFS, "No buffer space available" },
46  { WSAEISCONN, "Transport endpoint is already connected" },
47  { WSAENOTCONN, "Transport endpoint is not connected" },
48  { WSAESHUTDOWN, "Cannot send after transport endpoint shutdown" },
49  { WSAETOOMANYREFS, "Too many references: cannot splice" },
50  { WSAETIMEDOUT, "Connection timed out" },
51  { WSAECONNREFUSED, "Connection refused" },
52  { WSAELOOP, "Too many symbolic links encountered" },
53  { WSAENAMETOOLONG, "File name too long" },
54  { WSAEHOSTDOWN, "Host is down" },
55  { WSAEHOSTUNREACH, "No route to host" },
56  { WSAENOTEMPTY, "Directory not empty" },
57  { WSAEPROCLIM, "Process limit reached" },
58  { WSAEUSERS, "Too many users" },
59  { WSAEDQUOT, "Disk quota exceeded" },
60  { WSAESTALE, "Stale file handle" },
61  { WSAEREMOTE, "Object is remote" },
62  { WSAEDISCON, "Disconnected" },
63  { WSAENOMORE, "No more data" },
64  { WSAECANCELLED, "Operation cancelled" },
65  { WSAEINVALIDPROCTABLE, "Invalid process table" },
66  { WSAEINVALIDPROVIDER, "Invalid provider" },
67  { WSAEPROVIDERFAILEDINIT, "Provider failed to initialize" },
68  { WSAEREFUSED, "Operation refused" },
69  { 0, NULL }
70 };
71 
72 static const char *wv_errmap(int errnum)
73 {
74 
75  for (WvErrMap *i = wverrmap; i->num; i++)
76  if (i->num == errnum)
77  return i->str;
78  return NULL;
79 }
80 
81 #endif
82 
83 WvErrorBase::~WvErrorBase()
84 {
85  // nothing special
86 }
87 
88 
89 // win32's strerror() function is incredibly weak, so we'll provide a better
90 // one.
92 {
93  assert(errnum >= 0);
94 
95 #ifndef _WIN32
96  return ::strerror(errnum);
97 #else
98  const char *wverr = wv_errmap(errnum);
99  if (wverr)
100  return wverr;
101  else if (errnum >= WSABASEERR && errnum < WSABASEERR+2000)
102  {
103  // otherwise, an unrecognized winsock error: try getting the error
104  // message from win32.
105  char msg[4096];
106  const HMODULE module = GetModuleHandle("winsock.dll");
107  DWORD result = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
108  module, errnum, 0, msg, sizeof(msg), 0);
109  if (result)
110  return msg;
111 
112  DWORD e = GetLastError();
113  return WvString("Unknown format %s for error %s", e, errnum);
114  }
115  else
116  {
117  const char *str = ::strerror(errnum);
118  if (!strcmp(str, "Unknown error"))
119  return WvString("Unknown win32 error #%s", errnum);
120  else
121  return str;
122  }
123 #endif
124 }
125 
126 
127 WvString WvErrorBase::errstr() const
128 {
129  int errnum = geterr();
130 
131  if (errnum < 0)
132  {
133  assert(!!errstring);
134  return errstring;
135  }
136  else
137  {
138  if (!!errstring) return errstring;
139  return WvErrorBase::strerror(errnum);
140  }
141 }
142 
143 
144 void WvErrorBase::seterr(int _errnum)
145 {
146  if (!errnum)
147  {
148  assert((_errnum != -1 || !!errstring)
149  && "attempt to set errnum to -1 without also setting errstring");
150 #ifdef _WIN32
151  if (_errnum == WSAECONNABORTED)
152  _errnum = WSAECONNREFUSED; // work around WINE bug
153 #endif
154  errnum = _errnum;
155  }
156 }
157 
158 
159 void WvErrorBase::seterr(WvStringParm specialerr)
160 {
161  assert(!!specialerr);
162  if (!errnum)
163  {
164  errstring = specialerr;
165  seterr(-1);
166  }
167 }
168 
169 
170 void WvErrorBase::seterr(const WvErrorBase &err)
171 {
172  if (err.geterr() > 0)
173  seterr(err.geterr());
174  else if (err.geterr() < 0)
175  seterr(err.errstr());
176 }
177 
178 
179 void WvErrorBase::seterr_both(int _errnum, WvStringParm specialerr)
180 {
181  assert(!!specialerr);
182  if (!errnum)
183  {
184  errstring = specialerr;
185  seterr(_errnum);
186  }
187 }
WvErrorBase::geterr
virtual int geterr() const
If isok() is false, return the system error number corresponding to the error, -1 for a special error...
Definition: wverror.h:48
WvErrorBase::strerror
static WvString strerror(int errnum)
A replacement for the operating system ::strerror() function that can map more kinds of error strings...
Definition: wverror.cc:91
WvErrorBase::seterr
virtual void seterr(int _errnum)
Set the errnum variable – we have an error.
Definition: wverror.cc:144
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvErrorBase
A class for managing error numbers and strings.
Definition: wverror.h:23