Make WvStreams compile with gcc 4.4.
[wvstreams.git] / utils / wverror.cc
blobb9e96cdf8400719b5d413f552ac14c61bd044b93
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>
10 #ifdef _WIN32
11 #include "windows.h"
13 struct WvErrMap {
14 int num;
15 const char *str;
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 }
72 static const char *wv_errmap(int errnum)
75 for (WvErrMap *i = wverrmap; i->num; i++)
76 if (i->num == errnum)
77 return i->str;
78 return NULL;
81 #endif
83 WvErrorBase::~WvErrorBase()
85 // nothing special
89 // win32's strerror() function is incredibly weak, so we'll provide a better
90 // one.
91 WvString WvErrorBase::strerror(int errnum)
93 assert(errnum >= 0);
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)
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;
112 DWORD e = GetLastError();
113 return WvString("Unknown format %s for error %s", e, errnum);
115 else
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;
123 #endif
127 WvString WvErrorBase::errstr() const
129 int errnum = geterr();
131 if (errnum < 0)
133 assert(!!errstring);
134 return errstring;
136 else
138 if (!!errstring) return errstring;
139 return WvErrorBase::strerror(errnum);
144 void WvErrorBase::seterr(int _errnum)
146 if (!errnum)
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;
159 void WvErrorBase::seterr(WvStringParm specialerr)
161 assert(!!specialerr);
162 if (!errnum)
164 errstring = specialerr;
165 seterr(-1);
170 void WvErrorBase::seterr(const WvErrorBase &err)
172 if (err.geterr() > 0)
173 seterr(err.geterr());
174 else if (err.geterr() < 0)
175 seterr(err.errstr());
179 void WvErrorBase::seterr_both(int _errnum, WvStringParm specialerr)
181 assert(!!specialerr);
182 if (!errnum)
184 errstring = specialerr;
185 seterr(_errnum);