aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/net/natPlainSocketImpl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/net/natPlainSocketImpl.cc')
-rw-r--r--libjava/java/net/natPlainSocketImpl.cc177
1 files changed, 177 insertions, 0 deletions
diff --git a/libjava/java/net/natPlainSocketImpl.cc b/libjava/java/net/natPlainSocketImpl.cc
new file mode 100644
index 0000000..076ee71
--- /dev/null
+++ b/libjava/java/net/natPlainSocketImpl.cc
@@ -0,0 +1,177 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cni.h>
+#include <java/io/IOException.h>
+#include <java/io/FileDescriptor.h>
+#include <java/net/PlainSocketImpl.h>
+#include <java/net/InetAddress.h>
+
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+union SockAddr
+{
+ struct sockaddr_in address;
+#ifdef HAVE_INET6
+ struct sockaddr_in6 address6;
+#endif
+};
+
+void
+java::net::PlainSocketImpl::create (jboolean stream)
+{
+ int sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
+ if (sock < 0)
+ {
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.create: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+ }
+ fnum = sock;
+ fd = new java::io::FileDescriptor (sock);
+}
+
+void
+java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport)
+{
+ union SockAddr u;
+ jbyteArray haddress = host->address;
+ jbyte *bytes = elements (haddress);
+ int len = haddress->length;
+ struct sockaddr *ptr = (struct sockaddr *) &u.address;
+ if (len == 4)
+ {
+ u.address.sin_family = AF_INET;
+ memcpy (&u.address.sin_addr, bytes, len);
+ len = sizeof (struct sockaddr_in);
+ u.address.sin_port = htons (lport);
+ }
+#ifdef HAVE_INET6
+ else if (len == 16)
+ {
+ u.address6.sin6_family = AF_INET6;
+ memcpy (&u.address6.sin6_addr, bytes, len);
+ len = sizeof (struct sockaddr_in6);
+ u.address6.sin6_port = htons (lport);
+ }
+#endif
+ else
+ goto error;
+ if (::bind (fnum, ptr, len) == 0)
+ {
+ address = host;
+ localport = lport;
+ return;
+ }
+ error:
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.bind: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+}
+
+void
+java::net::PlainSocketImpl::connect (java::net::InetAddress *host, jint rport)
+{
+ union SockAddr u;
+ jbyteArray haddress = host->address;
+ jbyte *bytes = elements (haddress);
+ int len = haddress->length;
+ struct sockaddr *ptr = (struct sockaddr *) &u.address;
+ if (len == 4)
+ {
+ u.address.sin_family = AF_INET;
+ memcpy (&u.address.sin_addr, bytes, len);
+ len = sizeof (struct sockaddr_in);
+ u.address.sin_port = htons (rport);
+ }
+#ifdef HAVE_INET6
+ else if (len == 16)
+ {
+ u.address6.sin6_family = AF_INET6;
+ memcpy (&u.address6.sin6_addr, bytes, len);
+ len = sizeof (struct sockaddr_in6);
+ u.address6.sin6_port = htons (rport);
+ }
+#endif
+ else
+ goto error;
+ if (::connect (fnum, ptr, len) == 0)
+ {
+ address = host;
+ port = rport;
+ return;
+ }
+ error:
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.connect: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+}
+
+void
+java::net::PlainSocketImpl::listen (jint backlog)
+{
+ if (::listen (fnum, backlog) != 0)
+ {
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.listen: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+ }
+}
+
+void
+java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s)
+{
+ union SockAddr u;
+ socklen_t addrlen = sizeof(u);
+ int new_socket = ::accept (fnum, (sockaddr*) &u, &addrlen);
+ if (new_socket < 0)
+ goto error;
+ jbyteArray raddr;
+ jint rport;
+ if (u.address.sin_family == AF_INET)
+ {
+ raddr = JvNewByteArray (4);
+ memcpy (elements (raddr), &u.address.sin_addr, 4);
+ rport = ntohs (u.address.sin_port);
+ }
+#ifdef HAVE_INET6
+ {
+ raddr = JvNewByteArray (16);
+ memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+ rport = ntohs (u.address6.sin6_port);
+ }
+#endif
+ else
+ goto error;
+ s->fnum = new_socket;
+ s->localport = localport;
+ s->address = new InetAddress (raddr, NULL);
+ s->port = rport;
+ s->fd = new java::io::FileDescriptor (new_socket);
+ return;
+ error:
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.accept: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+}