update changelog
[alioth/cvs.git] / windows-NT / sockerror.c
1 /* sockerror.c --- convert WinSock error number to string
2    Vince Del Vecchio <vdelvecc@spd.analog.com>
3
4    This file is part of GNU CVS.
5
6    GNU CVS is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.  */
15
16 #include <stdio.h>
17 #include <sys/socket.h>
18
19 struct err_strs {
20     char **strs;
21     int first;
22     int last;
23 };
24
25 static char *errs1[] = {
26     /* EINTR            */ "Interrupted system call"
27 };
28
29 static char *errs2[] = {
30     /* EBADF            */ "Bad file descriptor"
31 };
32
33 static char *errs3[] = {
34     /* EACCES           */ "Permission denied",
35     /* EFAULT           */ "Bad address"
36 };
37
38 static char *errs4[] = {
39     /* EINVAL           */ "Invalid argument"
40 };
41
42 static char *errs5[] = {
43     /* EMFILE           */ "Too many open files",
44 };
45
46 static char *errs6[] = {
47     /* EWOULDBLOCK      */ "Resource temporarily unavailable",
48     /* EINPROGRESS      */ "Operation now in progress",
49     /* EALREADY         */ "Operation already in progress",
50     /* ENOTSOCK         */ "Socket operation on non-socket",
51     /* EDESTADDRREQ     */ "Destination address required",
52     /* EMSGSIZE         */ "Message too long",
53     /* EPROTOTYPE       */ "Protocol wrong type for socket",
54     /* ENOPROTOOPT      */ "Protocol not available",
55     /* EPROTONOSUPPORT  */ "Protocol not supported",
56     /* ESOCKTNOSUPPORT  */ "Socket type not supported",
57     /* EOPNOTSUPP       */ "Operation not supported on socket",
58     /* EPFNOSUPPORT     */ "Protocol family not supported",
59     /* EAFNOSUPPORT     */ "Address family not supported by protocol",
60     /* EADDRINUSE       */ "Address already in use",
61     /* EADDRNOTAVAIL    */ "Can't assign requested address",
62     /* ENETDOWN         */ "Network is down",
63     /* ENETUNREACH      */ "Network is unreachable",
64     /* ENETRESET        */ "Network connection dropped on reset",
65     /* ECONNABORTED     */ "Software caused connection abort",
66     /* ECONNRESET       */ "Connection reset by peer",
67     /* ENOBUFS          */ "No buffer space available",
68     /* EISCONN          */ "Socket is already connected",
69     /* ENOTCONN         */ "Socket is not connected",
70     /* ESHUTDOWN        */ "Can't send after socket shutdown",
71     /* ETOOMANYREFS     */ "Too many references: can't splice",
72     /* ETIMEDOUT        */ "Connection timed out",
73     /* ECONNREFUSED     */ "Connection refused",
74     /* ELOOP            */ "Too many levels of symbolic links",
75     /* ENAMETOOLONG     */ "File name too long",
76     /* EHOSTDOWN        */ "Host is down",
77     /* EHOSTUNREACH     */ "No route to host",
78     /* ENOTEMPTY        */ "Directory not empty",
79     /* EPROCLIM         */ "Too many processes",
80     /* EUSERS           */ "Too many users",
81     /* EDQUOT           */ "Disc quota exceeded",
82     /* ESTALE           */ "Stale NFS file handle",
83     /* EREMOTE          */ "Object is remote"
84 };
85
86 static char *errs7[] = {
87     /* SYSNOTREADY      */ "Network subsystem unavailable",
88     /* VERNOTSUPPORTED  */ "Requested WinSock version not supported",
89     /* NOTINITIALISED   */ "WinSock was not initialized"
90 };
91
92 #ifdef WSAEDISCON
93 static char *errs8[] = {
94     /* EDISCON          */ "Graceful shutdown in progress"
95 };
96 #endif
97
98 static char *errs9[] = {
99     /* HOST_NOT_FOUND   */ "Unknown host",
100     /* TRY_AGAIN        */ "Host name lookup failure",
101     /* NO_RECOVERY      */ "Unknown server error",
102     /* NO_DATA          */ "No address associated with name",
103 };
104
105 /* Some of these errors are defined in the winsock.h header file I have,
106    but not in the Winsock 1.1 spec.  I include them some of them anyway,
107    where it is not too hard to avoid referencing the symbolic constant. */
108
109 static struct err_strs sock_errlist[] = {
110     { errs1,    WSAEINTR,       WSAEINTR },
111     { errs2,    WSAEBADF,       WSAEBADF },
112     { errs3,    WSAEACCES,      WSAEFAULT },
113     { errs4,    WSAEINVAL,      WSAEINVAL },
114     { errs5,    WSAEMFILE,      WSAEMFILE },
115     { errs6,    WSAEWOULDBLOCK, WSAEHOSTUNREACH + 6 },
116     { errs7,    WSASYSNOTREADY, WSANOTINITIALISED },
117 #ifdef WSAEDISCON
118     { errs8,    WSAEDISCON,     WSAEDISCON },
119 #endif
120     { errs9,    WSAHOST_NOT_FOUND, WSANO_DATA }
121 };
122
123 char *
124 sock_strerror (int errnum)
125 {
126     static char buf[40];
127     int i;
128
129     for (i = 0; i < (sizeof sock_errlist / sizeof *sock_errlist); i++)
130     {
131         if (errnum >= sock_errlist[i].first && errnum <= sock_errlist[i].last)
132             return sock_errlist[i].strs[errnum - sock_errlist[i].first];
133     }
134     sprintf(buf, "Unknown socket error: %d", errnum);
135     return buf;
136 }