00001
00002
00003
00004
00005
00006
00007 #include "wverror.h"
00008 #include <assert.h>
00009
00010 #ifdef _WIN32
00011 #include "windows.h"
00012
00013 struct WvErrMap {
00014 int num;
00015 const char *str;
00016 };
00017
00018 static WvErrMap wverrmap[] = {
00019 { WSAEINTR, "Interrupted" },
00020 { WSAEBADF, "Bad file descriptor" },
00021 { WSAEACCES, "Access denied" },
00022 { WSAEFAULT, "Bad address" },
00023 { WSAEINVAL, "Invalid argument" },
00024 { WSAEMFILE, "Too many open files" },
00025 { WSAEWOULDBLOCK, "Operation would block" },
00026 { WSAEINPROGRESS, "Operation now in progress" },
00027 { WSAEALREADY, "Operation already in progress" },
00028 { WSAENOTSOCK, "Socket operation on non-socket" },
00029 { WSAEDESTADDRREQ, "Destination address required" },
00030 { WSAEMSGSIZE, "Message too long" },
00031 { WSAEPROTOTYPE, "Protocol wrong type for socket" },
00032 { WSAENOPROTOOPT, "Protocol not available" },
00033 { WSAEPROTONOSUPPORT, "Protocol not supported" },
00034 { WSAESOCKTNOSUPPORT, "Socket type not supported" },
00035 { WSAEOPNOTSUPP, "Operation not supported on transport endpoint" },
00036 { WSAEPFNOSUPPORT, "Protocol family not supported" },
00037 { WSAEAFNOSUPPORT, "Address family not supported by protocol" },
00038 { WSAEADDRINUSE, "Address already in use" },
00039 { WSAEADDRNOTAVAIL, "Cannot assign requested address" },
00040 { WSAENETDOWN, "Network is down" },
00041 { WSAENETUNREACH, "Network is unreachable" },
00042 { WSAENETRESET, "Network dropped connection because of reset" },
00043 { WSAECONNABORTED, "Software caused connection abort" },
00044 { WSAECONNRESET, "Connection reset by peer" },
00045 { WSAENOBUFS, "No buffer space available" },
00046 { WSAEISCONN, "Transport endpoint is already connected" },
00047 { WSAENOTCONN, "Transport endpoint is not connected" },
00048 { WSAESHUTDOWN, "Cannot send after transport endpoint shutdown" },
00049 { WSAETOOMANYREFS, "Too many references: cannot splice" },
00050 { WSAETIMEDOUT, "Connection timed out" },
00051 { WSAECONNREFUSED, "Connection refused" },
00052 { WSAELOOP, "Too many symbolic links encountered" },
00053 { WSAENAMETOOLONG, "File name too long" },
00054 { WSAEHOSTDOWN, "Host is down" },
00055 { WSAEHOSTUNREACH, "No route to host" },
00056 { WSAENOTEMPTY, "Directory not empty" },
00057 { WSAEPROCLIM, "Process limit reached" },
00058 { WSAEUSERS, "Too many users" },
00059 { WSAEDQUOT, "Disk quota exceeded" },
00060 { WSAESTALE, "Stale file handle" },
00061 { WSAEREMOTE, "Object is remote" },
00062 { WSAEDISCON, "Disconnected" },
00063 { WSAENOMORE, "No more data" },
00064 { WSAECANCELLED, "Operation cancelled" },
00065 { WSAEINVALIDPROCTABLE, "Invalid process table" },
00066 { WSAEINVALIDPROVIDER, "Invalid provider" },
00067 { WSAEPROVIDERFAILEDINIT, "Provider failed to initialize" },
00068 { WSAEREFUSED, "Operation refused" },
00069 { 0, NULL }
00070 };
00071
00072 static const char *wv_errmap(int errnum)
00073 {
00074
00075 for (WvErrMap *i = wverrmap; i->num; i++)
00076 if (i->num == errnum)
00077 return i->str;
00078 return NULL;
00079 }
00080
00081 #endif
00082
00083 WvErrorBase::~WvErrorBase()
00084 {
00085
00086 }
00087
00088
00089
00090
00091 WvString WvErrorBase::strerror(int errnum)
00092 {
00093 assert(errnum >= 0);
00094
00095 #ifndef _WIN32
00096 return ::strerror(errnum);
00097 #else
00098 const char *wverr = wv_errmap(errnum);
00099 if (wverr)
00100 return wverr;
00101 else if (errnum >= WSABASEERR && errnum < WSABASEERR+2000)
00102 {
00103
00104
00105 char msg[4096];
00106 const HMODULE module = GetModuleHandle("winsock.dll");
00107 DWORD result = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
00108 module, errnum, 0, msg, sizeof(msg), 0);
00109 if (result)
00110 return msg;
00111
00112 DWORD e = GetLastError();
00113 return WvString("Unknown format %s for error %s", e, errnum);
00114 }
00115 else
00116 {
00117 const char *str = ::strerror(errnum);
00118 if (!strcmp(str, "Unknown error"))
00119 return WvString("Unknown win32 error #%s", errnum);
00120 else
00121 return str;
00122 }
00123 #endif
00124 }
00125
00126
00127 WvString WvErrorBase::errstr() const
00128 {
00129 int errnum = geterr();
00130
00131 if (errnum < 0)
00132 {
00133 assert(!!errstring);
00134 return errstring;
00135 }
00136 else
00137 {
00138 if (!!errstring) return errstring;
00139 return WvErrorBase::strerror(errnum);
00140 }
00141 }
00142
00143
00144 void WvErrorBase::seterr(int _errnum)
00145 {
00146 if (!errnum)
00147 {
00148 assert(_errnum != -1 || !!errstring
00149 && "attempt to set errnum to -1 without also setting errstring");
00150 #ifdef _WIN32
00151 if (_errnum == WSAECONNABORTED)
00152 _errnum = WSAECONNREFUSED;
00153 #endif
00154 errnum = _errnum;
00155 }
00156 }
00157
00158
00159 void WvErrorBase::seterr(WvStringParm specialerr)
00160 {
00161 assert(!!specialerr);
00162 if (!errnum)
00163 {
00164 errstring = specialerr;
00165 seterr(-1);
00166 }
00167 }
00168
00169
00170 void WvErrorBase::seterr(const WvErrorBase &err)
00171 {
00172 if (err.geterr() > 0)
00173 seterr(err.geterr());
00174 else if (err.geterr() < 0)
00175 seterr(err.errstr());
00176 }
00177
00178
00179 void WvErrorBase::seterr_both(int _errnum, WvStringParm specialerr)
00180 {
00181 assert(!!specialerr);
00182 if (!errnum)
00183 {
00184 errstring = specialerr;
00185 seterr(_errnum);
00186 }
00187 }