[Patch for Review] "errno" in networking code and Win32
Ranjit Mathew
rmathew@hotmail.com
Sat Jan 4 19:54:00 GMT 2003
Hi,
The following patch proposes to clean up the networking
code a little bit with respect to checking for errors during
socket operations.
The background information for the need for such a patch can
be found in the following message I posted to the GCJ list:
http://gcc.gnu.org/ml/java/2002-12/msg00218.html
I would especially request Adam and Michael (Koch) to review
these proposals since code written by them would be the most
affected by these changes.
In summary, the normal UNIX "errno" variable cannot be used on
Win32 to check for errors in calls to socket functions - the
Win32 WinSock 2 API mandates the use of the WSAGetLastError( ) and
WSASetLastError( ) functions to get and set the error code for
WinSock 2 functions. Moreover, the normal socket error code
definitions like ECONNREFUSED, etc. are instead defined as
WSAECONNREFUSED, etc.
To accommodate this limitation, I propose defining macros
"_Jv_platform_getsockerr()" and "_Jv_platform_setsockerr()"
instead of directly manipulating the errno variable for
networking code. I also provide mappings for the normal
socket error codes to their WinSock2 counterparts. For Posix
these macros directly manipulate "errno" while on Win32
these macros call WSAGetLastError( ) and WSASetLastError( )
respectively.
IMPORTANT: If these changes are acceptable, from now on we should
use these macros in our networking code instead of using "errno"
directly.
NOTE: I must point out that even after making these changes,
the networking code would still be lacking on Win32 because you
just cannot use the strerror( ) function to get the error
message for a socket error - you must use the FormatMessage( )
Win32 function to do it. This is a bit involved and I will
attempt it a bit later - in the mean time strerror( ) will
return messages like "Unknown Error" for socket errors instead
of the "real" error message.
I have had to replace the "winsock.h" header with "ws2tcpip.h"
in win32.h. I have also removed the original pseudo definitions
of ENOTCONN and ECONNRESET in win32.h as well as that of
ENOPROTOPT.
ChangeLog:
2003-01-04 Ranjit Mathew <rmathew@hotmail.com>
* include/win32.h: Use "ws2tcpip.h" instead of "winsock.h".
Map socket error codes like EFOOBAR to WinSock WSAFOOBAR
error codes.
(ENOTCONN, ECONNRESET, ENOPROTOOPT): Remove old definitions.
(_Jv_platform_getsockerr): Define.
(_Jv_platform_setsockerr): Define.
* include/posix.h (_Jv_platform_getsockerr): Define.
(_Jv_platform_setsockerr): Define.
* java/net/natPlainDatagramSocketImpl.cc: Use
_Jv_platform_getsockerr and _Jv_platform_setsockerr instead
of directly using "errno".
* java/net/natPlainDatagramSocketImpl.cc: Ditto.
-------------------------------- 8< --------------------------------
--- include/win32.h 2002-12-18 23:28:14.000000000 +0530
+++ include/win32.h 2003-01-05 00:12:45.000000000 +0530
@@ -15,6 +15,5 @@
#undef STRICT
-#undef __INSIDE_CYGWIN__
-#include <winsock.h>
+#include <ws2tcpip.h>
#define IP_TOS 3
#include <gcj/cni.h>
@@ -29,13 +28,40 @@
#ifndef DISABLE_JAVA_NET
-// these errors cannot occur on Win32
-#define ENOTCONN 0
-#define ECONNRESET 0
-
-#ifndef ENOPROTOOPT
-#define ENOPROTOOPT 109
-#endif
+#define _Jv_platform_getsockerr() WSAGetLastError( )
+#define _Jv_platform_setsockerr(x) WSASetLastError(x)
-#endif // DISABLE_JAVA_NET
+#define EUSERS WSAEUSERS
+#define ENOTSOCK WSAENOTSOCK
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#define EMSGSIZE WSAEMSGSIZE
+#define EPROTOTYPE WSAEPROTOTYPE
+#define ENOPROTOOPT WSAENOPROTOOPT
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define EADDRINUSE WSAEADDRINUSE
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#define ENETDOWN WSAENETDOWN
+#define ENETUNREACH WSAENETUNREACH
+#define ENETRESET WSAENETRESET
+#define ECONNABORTED WSAECONNABORTED
+#define ECONNRESET WSAECONNRESET
+#define ENOBUFS WSAENOBUFS
+#define EISCONN WSAEISCONN
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#define ETIMEDOUT WSAETIMEDOUT
+#define ECONNREFUSED WSAECONNREFUSED
+#define EHOSTDOWN WSAEHOSTDOWN
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#define EALREADY WSAEALREADY
+#define EINPROGRESS WSAEINPROGRESS
+#define ESTALE WSAESTALE
+#define EDQUOT WSAEDQUOT
+
+#endif /* !DISABLE_JAVA_NET */
extern void _Jv_platform_initialize (void);
--- include/posix.h 2003-01-04 20:56:53.000000000 +0530
+++ include/posix.h 2003-01-05 00:01:53.000000000 +0530
@@ -67,4 +67,7 @@
#endif
+#define _Jv_platform_getsockerr() (errno)
+#define _Jv_platform_setsockerr(x) (errno = (x))
+
static inline int
_Jv_socket (int domain, int type, int protocol)
--- java/net/natPlainDatagramSocketImpl.cc 2002-12-18 23:47:26.000000000 +0530
+++ java/net/natPlainDatagramSocketImpl.cc 2003-01-05 00:18:39.000000000 +0530
@@ -311,5 +311,5 @@
char* strerr = strerror (errno);
- if (errno == ECONNREFUSED)
+ if (_Jv_platform_getsockerr () == ECONNREFUSED)
throw new PortUnreachableException (JvNewStringUTF (strerr));
@@ -378,5 +378,5 @@
char* strerr = strerror (errno);
- if (errno == ECONNREFUSED)
+ if (_Jv_platform_getsockerr () == ECONNREFUSED)
throw new PortUnreachableException (JvNewStringUTF (strerr));
@@ -433,5 +433,5 @@
char* strerr = strerror (errno);
- if (errno == ECONNREFUSED)
+ if (_Jv_platform_getsockerr () == ECONNREFUSED)
throw new PortUnreachableException (JvNewStringUTF (strerr));
@@ -500,5 +500,5 @@
char* strerr = strerror (errno);
- if (errno == ECONNREFUSED)
+ if (_Jv_platform_getsockerr () == ECONNREFUSED)
throw new PortUnreachableException (JvNewStringUTF (strerr));
@@ -728,5 +728,5 @@
return;
default :
- errno = ENOPROTOOPT;
+ _Jv_platform_setsockerr (ENOPROTOOPT);
}
@@ -862,5 +862,5 @@
default :
- errno = ENOPROTOOPT;
+ _Jv_platform_setsockerr (ENOPROTOOPT);
}
--- java/net/natPlainSocketImpl.cc 2003-01-05 00:03:33.000000000 +0530
+++ java/net/natPlainSocketImpl.cc 2003-01-05 00:09:09.000000000 +0530
@@ -323,5 +323,6 @@
::fcntl (fnum, F_SETFL, flags | O_NONBLOCK);
- if ((_Jv_connect (fnum, ptr, len) != 0) && (errno != EINPROGRESS))
+ if ((_Jv_connect (fnum, ptr, len) != 0) &&
+ (_Jv_platform_getsockerr () != EINPROGRESS))
goto error;
@@ -454,5 +455,7 @@
// These three errors are not errors according to tests performed
// on the reference implementation.
- if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF)
+ if (_Jv_platform_getsockerr () != ENOTCONN &&
+ _Jv_platform_getsockerr () != ECONNRESET &&
+ _Jv_platform_getsockerr () != EBADF)
throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
}
@@ -483,5 +486,7 @@
}
// Some errors should not cause exceptions.
- if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF)
+ if (_Jv_platform_getsockerr () != ENOTCONN &&
+ _Jv_platform_getsockerr () != ECONNRESET &&
+ _Jv_platform_getsockerr () != EBADF)
throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
break;
@@ -517,5 +522,7 @@
}
// Some errors should not cause exceptions.
- if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF)
+ if (_Jv_platform_getsockerr () != ENOTCONN &&
+ _Jv_platform_getsockerr () != ECONNRESET &&
+ _Jv_platform_getsockerr () != EBADF)
throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
break;
@@ -583,5 +590,5 @@
{
// Some errors cause us to return end of stream...
- if (errno == ENOTCONN)
+ if (_Jv_platform_getsockerr () == ENOTCONN)
return -1;
@@ -654,5 +661,5 @@
{
// Some errors cause us to return end of stream...
- if (errno == ENOTCONN)
+ if (_Jv_platform_getsockerr () == ENOTCONN)
return -1;
@@ -676,5 +683,5 @@
r = ::ioctl (fnum, FIONREAD, &num);
- if (r == -1 && errno == ENOTTY)
+ if (r == -1 && _Jv_platform_getsockerr () == ENOTTY)
{
// If the ioctl doesn't work, we don't care.
@@ -687,5 +694,5 @@
if (fnum < 0)
{
- errno = EBADF;
+ _Jv_platform_setsockerr (EBADF);
r = -1;
}
@@ -852,5 +859,5 @@
default :
- errno = ENOPROTOOPT;
+ _Jv_platform_setsockerr (ENOPROTOOPT);
}
@@ -995,5 +1002,5 @@
default :
- errno = ENOPROTOOPT;
+ _Jv_platform_setsockerr (ENOPROTOOPT);
}
-------------------------------- 8< --------------------------------
Sincerely Yours,
Ranjit.
--
Ranjit Mathew Email: rmathew AT hotmail DOT com
Bangalore,
INDIA. Web: http://ranjitmathew.tripod.com/
More information about the Java-patches
mailing list