From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libjava/classpath/native/jni/java-net/.cvsignore | 8 + libjava/classpath/native/jni/java-net/Makefile.am | 26 + libjava/classpath/native/jni/java-net/Makefile.in | 637 +++++++++ .../jni/java-net/gnu_java_net_VMPlainSocketImpl.c | 965 +++++++++++++ .../java-net/gnu_java_net_local_LocalSocketImpl.c | 517 +++++++ .../native/jni/java-net/java_net_VMInetAddress.c | 395 ++++++ .../jni/java-net/java_net_VMNetworkInterface.c | 399 ++++++ .../native/jni/java-net/java_net_VMURLConnection.c | 102 ++ libjava/classpath/native/jni/java-net/javanet.c | 1500 ++++++++++++++++++++ libjava/classpath/native/jni/java-net/javanet.h | 101 ++ libjava/classpath/native/jni/java-net/local.c | 189 +++ libjava/classpath/native/jni/java-net/local.h | 28 + 12 files changed, 4867 insertions(+) create mode 100644 libjava/classpath/native/jni/java-net/.cvsignore create mode 100644 libjava/classpath/native/jni/java-net/Makefile.am create mode 100644 libjava/classpath/native/jni/java-net/Makefile.in create mode 100644 libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c create mode 100644 libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c create mode 100644 libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c create mode 100644 libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c create mode 100644 libjava/classpath/native/jni/java-net/java_net_VMURLConnection.c create mode 100644 libjava/classpath/native/jni/java-net/javanet.c create mode 100644 libjava/classpath/native/jni/java-net/javanet.h create mode 100644 libjava/classpath/native/jni/java-net/local.c create mode 100644 libjava/classpath/native/jni/java-net/local.h (limited to 'libjava/classpath/native/jni/java-net') diff --git a/libjava/classpath/native/jni/java-net/.cvsignore b/libjava/classpath/native/jni/java-net/.cvsignore new file mode 100644 index 000000000..e9f2658a6 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/.cvsignore @@ -0,0 +1,8 @@ +*.o +*.a +*.lo +*.la +.libs +.deps +Makefile +Makefile.in diff --git a/libjava/classpath/native/jni/java-net/Makefile.am b/libjava/classpath/native/jni/java-net/Makefile.am new file mode 100644 index 000000000..f70086d93 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/Makefile.am @@ -0,0 +1,26 @@ +nativeexeclib_LTLIBRARIES = libjavanet.la + +if ENABLE_LOCAL_SOCKETS +local_sources = gnu_java_net_local_LocalSocketImpl.c \ + local.c \ + local.h +else +local_sources = gnu_java_net_local_LocalSocketImpl.c +endif + +libjavanet_la_SOURCES = javanet.c \ + javanet.h \ + java_net_VMInetAddress.c \ + java_net_VMNetworkInterface.c \ + java_net_VMURLConnection.c \ + gnu_java_net_VMPlainSocketImpl.c \ + $(local_sources) + +libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \ + $(top_builddir)/native/jni/native-lib/libclasspathnative.la \ + $(LIBMAGIC) + +AM_LDFLAGS = @CLASSPATH_MODULE@ +AM_CPPFLAGS = @CLASSPATH_INCLUDES@ +AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@ \ + @EXTRA_CFLAGS@ diff --git a/libjava/classpath/native/jni/java-net/Makefile.in b/libjava/classpath/native/jni/java-net/Makefile.in new file mode 100644 index 000000000..ca3e16311 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/Makefile.in @@ -0,0 +1,637 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = native/jni/java-net +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \ + $(top_srcdir)/../../config/lead-dot.m4 \ + $(top_srcdir)/../../config/lib-ld.m4 \ + $(top_srcdir)/../../config/lib-link.m4 \ + $(top_srcdir)/../../config/lib-prefix.m4 \ + $(top_srcdir)/../../config/multi.m4 \ + $(top_srcdir)/../../config/no-executables.m4 \ + $(top_srcdir)/../../config/override.m4 \ + $(top_srcdir)/../../libtool.m4 \ + $(top_srcdir)/../../ltoptions.m4 \ + $(top_srcdir)/../../ltsugar.m4 \ + $(top_srcdir)/../../ltversion.m4 \ + $(top_srcdir)/../../lt~obsolete.m4 \ + $(top_srcdir)/m4/ac_prog_antlr.m4 \ + $(top_srcdir)/m4/ac_prog_java.m4 \ + $(top_srcdir)/m4/ac_prog_java_works.m4 \ + $(top_srcdir)/m4/ac_prog_javac.m4 \ + $(top_srcdir)/m4/ac_prog_javac_works.m4 \ + $(top_srcdir)/m4/acattribute.m4 $(top_srcdir)/m4/accross.m4 \ + $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/ax_create_stdint_h.m4 \ + $(top_srcdir)/m4/ax_func_which_gethostbyname_r.m4 \ + $(top_srcdir)/m4/gcc_attribute.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(nativeexeclibdir)" +LTLIBRARIES = $(nativeexeclib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libjavanet_la_DEPENDENCIES = \ + $(top_builddir)/native/jni/classpath/jcl.lo \ + $(top_builddir)/native/jni/native-lib/libclasspathnative.la \ + $(am__DEPENDENCIES_1) +@ENABLE_LOCAL_SOCKETS_FALSE@am__objects_1 = gnu_java_net_local_LocalSocketImpl.lo +@ENABLE_LOCAL_SOCKETS_TRUE@am__objects_1 = gnu_java_net_local_LocalSocketImpl.lo \ +@ENABLE_LOCAL_SOCKETS_TRUE@ local.lo +am_libjavanet_la_OBJECTS = javanet.lo java_net_VMInetAddress.lo \ + java_net_VMNetworkInterface.lo java_net_VMURLConnection.lo \ + gnu_java_net_VMPlainSocketImpl.lo $(am__objects_1) +libjavanet_la_OBJECTS = $(am_libjavanet_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/../../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libjavanet_la_SOURCES) +ETAGS = etags +CTAGS = ctags +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +ANTLR = @ANTLR@ +ANTLR_JAR = @ANTLR_JAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLASSPATH_CONVENIENCE = @CLASSPATH_CONVENIENCE@ +CLASSPATH_INCLUDES = @CLASSPATH_INCLUDES@ +CLASSPATH_MODULE = @CLASSPATH_MODULE@ +COLLECTIONS_PREFIX = @COLLECTIONS_PREFIX@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFAULT_PREFS_PEER = @DEFAULT_PREFS_PEER@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +ECJ_JAR = @ECJ_JAR@ +EGREP = @EGREP@ +ERROR_CFLAGS = @ERROR_CFLAGS@ +EXAMPLESDIR = @EXAMPLESDIR@ +EXEEXT = @EXEEXT@ +EXTRA_CFLAGS = @EXTRA_CFLAGS@ +FGREP = @FGREP@ +FIND = @FIND@ +FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +GCONF_CFLAGS = @GCONF_CFLAGS@ +GCONF_LIBS = @GCONF_LIBS@ +GDK_CFLAGS = @GDK_CFLAGS@ +GDK_LIBS = @GDK_LIBS@ +GJDOC = @GJDOC@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMP_CFLAGS = @GMP_CFLAGS@ +GMP_LIBS = @GMP_LIBS@ +GREP = @GREP@ +GSTREAMER_BASE_CFLAGS = @GSTREAMER_BASE_CFLAGS@ +GSTREAMER_BASE_LIBS = @GSTREAMER_BASE_LIBS@ +GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@ +GSTREAMER_FILE_READER = @GSTREAMER_FILE_READER@ +GSTREAMER_LIBS = @GSTREAMER_LIBS@ +GSTREAMER_MIXER_PROVIDER = @GSTREAMER_MIXER_PROVIDER@ +GSTREAMER_PLUGINS_BASE_CFLAGS = @GSTREAMER_PLUGINS_BASE_CFLAGS@ +GSTREAMER_PLUGINS_BASE_LIBS = @GSTREAMER_PLUGINS_BASE_LIBS@ +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +JAVAC_IS_GCJ = @JAVAC_IS_GCJ@ +JAVAC_MEM_OPT = @JAVAC_MEM_OPT@ +JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@ +JAY = @JAY@ +JAY_SKELETON = @JAY_SKELETON@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDEBUG = @LIBDEBUG@ +LIBICONV = @LIBICONV@ +LIBMAGIC = @LIBMAGIC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVERSION = @LIBVERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MOZILLA_CFLAGS = @MOZILLA_CFLAGS@ +MOZILLA_LIBS = @MOZILLA_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@ +PANGOFT2_LIBS = @PANGOFT2_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_TO_ESCHER = @PATH_TO_ESCHER@ +PATH_TO_GLIBJ_ZIP = @PATH_TO_GLIBJ_ZIP@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PLUGIN_DIR = @PLUGIN_DIR@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +REMOVE = @REMOVE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRICT_WARNING_CFLAGS = @STRICT_WARNING_CFLAGS@ +STRIP = @STRIP@ +TOOLSDIR = @TOOLSDIR@ +USER_JAVAH = @USER_JAVAH@ +VERSION = @VERSION@ +WANT_NATIVE_BIG_INTEGER = @WANT_NATIVE_BIG_INTEGER@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XMKMF = @XMKMF@ +XML_CFLAGS = @XML_CFLAGS@ +XML_LIBS = @XML_LIBS@ +XSLT_CFLAGS = @XSLT_CFLAGS@ +XSLT_LIBS = @XSLT_LIBS@ +XTEST_LIBS = @XTEST_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_ANTLR = @ac_ct_ANTLR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +default_toolkit = @default_toolkit@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +glibjdir = @glibjdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +nativeexeclibdir = @nativeexeclibdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uudecode = @uudecode@ +vm_classes = @vm_classes@ +nativeexeclib_LTLIBRARIES = libjavanet.la +@ENABLE_LOCAL_SOCKETS_FALSE@local_sources = gnu_java_net_local_LocalSocketImpl.c +@ENABLE_LOCAL_SOCKETS_TRUE@local_sources = gnu_java_net_local_LocalSocketImpl.c \ +@ENABLE_LOCAL_SOCKETS_TRUE@ local.c \ +@ENABLE_LOCAL_SOCKETS_TRUE@ local.h + +libjavanet_la_SOURCES = javanet.c \ + javanet.h \ + java_net_VMInetAddress.c \ + java_net_VMNetworkInterface.c \ + java_net_VMURLConnection.c \ + gnu_java_net_VMPlainSocketImpl.c \ + $(local_sources) + +libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \ + $(top_builddir)/native/jni/native-lib/libclasspathnative.la \ + $(LIBMAGIC) + +AM_LDFLAGS = @CLASSPATH_MODULE@ +AM_CPPFLAGS = @CLASSPATH_INCLUDES@ +AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@ \ + @EXTRA_CFLAGS@ + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu native/jni/java-net/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu native/jni/java-net/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-nativeexeclibLTLIBRARIES: $(nativeexeclib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(nativeexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(nativeexeclibdir)" + @list='$(nativeexeclib_LTLIBRARIES)'; test -n "$(nativeexeclibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(nativeexeclibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(nativeexeclibdir)"; \ + } + +uninstall-nativeexeclibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(nativeexeclib_LTLIBRARIES)'; test -n "$(nativeexeclibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(nativeexeclibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(nativeexeclibdir)/$$f"; \ + done + +clean-nativeexeclibLTLIBRARIES: + -test -z "$(nativeexeclib_LTLIBRARIES)" || rm -f $(nativeexeclib_LTLIBRARIES) + @list='$(nativeexeclib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libjavanet.la: $(libjavanet_la_OBJECTS) $(libjavanet_la_DEPENDENCIES) + $(LINK) -rpath $(nativeexeclibdir) $(libjavanet_la_OBJECTS) $(libjavanet_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_net_VMPlainSocketImpl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_net_local_LocalSocketImpl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_net_VMInetAddress.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_net_VMNetworkInterface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_net_VMURLConnection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javanet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(nativeexeclibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-nativeexeclibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-nativeexeclibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-nativeexeclibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-nativeexeclibLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-nativeexeclibLTLIBRARIES install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-nativeexeclibLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c new file mode 100644 index 000000000..c9620a4e7 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c @@ -0,0 +1,965 @@ +/* VMPlainSocketImpl.c - Native methods for PlainSocketImpl class + Copyright (C) 2005, 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +#ifdef HAVE_CONFIG_H +#include +#endif /* HAVE_CONFIG_H */ + +#include + +#include +#include +#include +#include +#ifdef HAVE_IFADDRS_H +#include +#endif +#include +#include +#ifdef HAVE_NET_IF_H +#include +#endif +#include +#include +#include +#include +#include + +#include +#include + +#include "cpnative.h" +#include "cpnet.h" +#include "cpio.h" +#include "javanet.h" + +#include "gnu_java_net_VMPlainSocketImpl.h" + +#define THROW_NO_NETWORK(env) JCL_ThrowException (env, "java/lang/InternalError", "this platform not configured for network support") +#define THROW_NO_IPV6(env) JCL_ThrowException (env, "java/lang/InternalError", "IPv6 support not available") + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: bind + * Signature: (I[BI)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_bind (JNIEnv *env, + jclass clazz __attribute__((unused)), + jint fd, jbyteArray addr, jint port) +{ + struct sockaddr_in sockaddr; + jbyte *elems = NULL; + int ret; + + if (addr != NULL) + elems = (*env)->GetByteArrayElements (env, addr, NULL); + + memset(&sockaddr, 0, sizeof (struct sockaddr_in)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons (port); + /* addr is already in network byte order. */ + if (elems != NULL) + sockaddr.sin_addr.s_addr = *((uint32_t *) elems); + else + sockaddr.sin_addr.s_addr = INADDR_ANY; + + /* bind(2) from BSD says bind will never return EINTR */ + /* bind is not a blocking system call */ + ret = bind (fd, (struct sockaddr *) &sockaddr, sizeof (struct sockaddr_in)); + + if (elems != NULL) + (*env)->ReleaseByteArrayElements (env, addr, elems, JNI_ABORT); + + if (-1 == ret) + JCL_ThrowException (env, BIND_EXCEPTION, strerror (errno)); + + cpio_closeOnExec(ret); +} + + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: bind6 + * Signature: (I[BI)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_bind6 (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jbyteArray addr, jint port) +{ +#ifdef HAVE_INET6 + struct sockaddr_in6 sockaddr; + jbyte *elems; + int ret; + + elems = (*env)->GetByteArrayElements (env, addr, NULL); + + memset (&sockaddr, 0, sizeof (struct sockaddr_in6)); + sockaddr.sin6_family = AF_INET6; + sockaddr.sin6_port = htons (port); + memcpy (&sockaddr.sin6_addr.s6_addr, elems, 16); + + /* bind(2) from BSD says bind will never return EINTR */ + /* bind is not a blocking system call */ + ret = bind (fd, (struct sockaddr *) &sockaddr, + sizeof (struct sockaddr_in6)); + + (*env)->ReleaseByteArrayElements (env, addr, elems, JNI_ABORT); + + if (-1 == ret) + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); +#else + THROW_NO_IPV6(env); +#endif +} + + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: listen + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_listen (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jint backlog) +{ + int ret; + + /* listen(2) says that this call will never return EINTR */ + /* listen is not a blocking system call */ + if ((ret = listen (fd, backlog)) == -1) + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); +} + + +/* These constants are also defined in java/net/SocketOptions.java. + * Except for CPNET_IP_TTL which is defined in + * vm/reference/gnu/java/net/VMPlainSocketImpl.java . + */ +enum java_sockopt { + CPNET_SO_KEEPALIVE = 0x8, + CPNET_SO_LINGER = 0x80, + CPNET_SO_TIMEOUT = 0x1006, + CPNET_SO_BINDADDR = 0x0F, + CPNET_SO_SNDBUF = 0x1001, + CPNET_SO_RCVBUF = 0x1002, + CPNET_SO_REUSEADDR = 0x04, + CPNET_SO_BROADCAST = 0x20, + CPNET_SO_OOBINLINE = 0x1003, + CPNET_TCP_NODELAY = 0x01, + CPNET_IP_MULTICAST_IF = 0x10, + CPNET_IP_MULTICAST_IF2 = 0x1F, + CPNET_IP_MULTICAST_LOOP = 0x12, + CPNET_IP_TOS = 0x03, + CPNET_IP_TTL = 0x1E61 +}; + + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: setOption + * Signature: (III)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_setOption (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jint option, jint value) +{ + enum java_sockopt joption = (enum java_sockopt) option; + int optname = -1; + int level = SOL_SOCKET; + const int _value = value; + struct linger _linger; + struct timeval _timeo; + void *optval = (void *) &_value; + socklen_t optlen = sizeof (int); + + switch (joption) + { + case CPNET_IP_MULTICAST_LOOP: + level = IPPROTO_IP; + optname = IP_MULTICAST_LOOP; + break; + + case CPNET_SO_KEEPALIVE: + optname = SO_KEEPALIVE; + break; + + case CPNET_SO_LINGER: + optname = SO_LINGER; + if (_value == -1) + _linger.l_onoff = 0; + else + _linger.l_onoff = 1; + _linger.l_linger = _value; + optval = &_linger; + optlen = sizeof (struct linger); + break; + + case CPNET_SO_TIMEOUT: + optname = SO_RCVTIMEO; + _timeo.tv_sec = value / 1000; + _timeo.tv_usec = (value % 1000) * 1000; + optval = &_timeo; + optlen = sizeof (struct timeval); + break; + + case CPNET_SO_SNDBUF: + optname = SO_SNDBUF; + break; + + case CPNET_SO_RCVBUF: + optname = SO_RCVBUF; + break; + + case CPNET_SO_REUSEADDR: + optname = SO_REUSEADDR; + break; + + case CPNET_SO_BROADCAST: + optname = SO_BROADCAST; + break; + + case CPNET_SO_OOBINLINE: + optname = SO_OOBINLINE; + break; + + case CPNET_TCP_NODELAY: + level = IPPROTO_TCP; + optname = TCP_NODELAY; + break; + + case CPNET_IP_TOS: + level = IPPROTO_IP; + optname = IP_TOS; + break; + + case CPNET_IP_TTL: + level = IPPROTO_IP; + optname = IP_TTL; + break; + + case CPNET_SO_BINDADDR: + case CPNET_IP_MULTICAST_IF: + case CPNET_IP_MULTICAST_IF2: + JCL_ThrowException (env, IO_EXCEPTION, "argument not a boolean or integer option"); + return; + } + + if (setsockopt (fd, level, optname, (const void *) optval, optlen) == -1) + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); +} + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: getOption + * Signature: (II)I + */ +JNIEXPORT jint JNICALL +Java_gnu_java_net_VMPlainSocketImpl_getOption (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jint option) +{ + enum java_sockopt joption = (enum java_sockopt) option; + int optname = -1; + int level = SOL_SOCKET; + int value; + struct linger linger; + struct timeval timeo; + void *optval = &value; + socklen_t optlen = sizeof (int); + + switch (joption) + { + case CPNET_IP_MULTICAST_LOOP: + level = IPPROTO_IP; + optname = IP_MULTICAST_LOOP; + break; + + case CPNET_SO_KEEPALIVE: + optname = SO_KEEPALIVE; + break; + + case CPNET_SO_LINGER: + optname = SO_LINGER; + optval = &linger; + optlen = sizeof (struct linger); + break; + + case CPNET_SO_TIMEOUT: + optname = SO_RCVTIMEO; + optval = &timeo; + optlen = sizeof (struct timeval); + break; + + case CPNET_SO_SNDBUF: + optname = SO_SNDBUF; + break; + + case CPNET_SO_RCVBUF: + optname = SO_RCVBUF; + break; + + case CPNET_SO_REUSEADDR: + optname = SO_REUSEADDR; + break; + + case CPNET_SO_BROADCAST: + optname = SO_BROADCAST; + break; + + case CPNET_SO_OOBINLINE: + optname = SO_OOBINLINE; + break; + + case CPNET_TCP_NODELAY: + level = IPPROTO_TCP; + optname = TCP_NODELAY; + break; + + case CPNET_IP_TOS: + level = IPPROTO_IP; + optname = IP_TOS; + break; + + case CPNET_IP_TTL: + level = IPPROTO_IP; + optname = IP_TTL; + break; + + case CPNET_SO_BINDADDR: + case CPNET_IP_MULTICAST_IF: + case CPNET_IP_MULTICAST_IF2: + JCL_ThrowException (env, IO_EXCEPTION, "argument not a boolean or integer option"); + return -1; + } + + if (getsockopt (fd, level, optname, optval, &optlen) == -1) + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); + + /* Returns the linger value if it is enabled or -1 in case + * it is disabled. This is how the Java API expects it. + */ + if (joption == CPNET_SO_LINGER) + return (linger.l_onoff) ? linger.l_linger : -1; + if (joption == CPNET_SO_TIMEOUT) + return (timeo.tv_sec * 1000) + (timeo.tv_usec / 1000); + + return value; +} + +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_setMulticastInterface (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, + jint optionId __attribute__((unused)), + jobject addr) +{ + int result; + cpnet_address *cpaddr = _javanet_get_ip_netaddr (env, addr); + + if ((*env)->ExceptionOccurred (env)) + return; + + result = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, + (struct sockaddr *) cpaddr->data, cpaddr->len); + + cpnet_freeAddress (env, cpaddr); + + if (result == -1) + JCL_ThrowException (env, SOCKET_EXCEPTION, cpnative_getErrorString (errno)); +} + +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_setMulticastInterface6 (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, + jint optionId __attribute__((unused)), + jstring ifname) +{ +#ifdef HAVE_SETSOCKOPT +#ifdef HAVE_INET6 + int result; + const char *str_ifname = JCL_jstring_to_cstring (env, ifname); + unsigned int if_index; + + if ((*env)->ExceptionOccurred (env)) + { + JCL_free_cstring(env, ifname, str_ifname); + return; + } + + if_index = if_nametoindex(str_ifname); + if (!if_index) + { + JCL_free_cstring(env, ifname, str_ifname); + JCL_ThrowException (env, SOCKET_EXCEPTION, "interface does not exist"); + return; + } + + result = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + (unsigned int *) &if_index, sizeof(if_index)); + + JCL_free_cstring(env, ifname, str_ifname); + + if (result == -1) + JCL_ThrowException (env, SOCKET_EXCEPTION, cpnative_getErrorString (errno)); +#else + (void) fd; + JCL_ThrowException (env, "java/lang/InternalError", + "IPv6 support not available"); +#endif /* HAVE_INET6 */ +#else + (void) fd; + THROW_NO_IPV6(env); +#endif /* HAVE_SETSOCKOPT */ +} + +JNIEXPORT jobject JNICALL +Java_gnu_java_net_VMPlainSocketImpl_getMulticastInterface (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, + jint optionId __attribute__((unused))) +{ + jobject obj; + cpnet_address *cpaddr; + int result = cpnet_getMulticastIF (env, fd, &cpaddr); + + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + obj = _javanet_create_inetaddress (env, cpaddr); + cpnet_freeAddress (env, cpaddr); + + return obj; +} + + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: shutdownInput + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_shutdownInput (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd) +{ + if (shutdown (fd, SHUT_RD) == -1) + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); +} + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: shutdownOutput + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_shutdownOutput (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd) +{ + if (shutdown (fd, SHUT_WR) == -1) + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); +} + + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: sendUrgentData + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_sendUrgentData (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jint data) +{ + const char x = (char) data; + + if (send (fd, &x, 1, MSG_OOB) == -1) + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); +} + + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: join + * Signature: (I[B)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_join (JNIEnv *env, + jclass clazz __attribute__((unused)), + jint fd, jbyteArray addr) +{ +#ifdef HAVE_SETSOCKOPT + struct ip_mreq maddr; + jbyte *addr_elems; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems); + maddr.imr_interface.s_addr = INADDR_ANY; + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &maddr, sizeof (struct ip_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); +#else + (void) fd; + (void) addr; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: join6 + * Signature: (I[B)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_join6 (JNIEnv *env, + jclass clazz __attribute__((unused)), + jint fd, jbyteArray addr) +{ +#ifdef HAVE_SETSOCKOPT +#ifdef HAVE_INET6 + struct ipv6_mreq maddr; + jbyte *addr_elems; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16); + maddr.ipv6mr_interface = 0; + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &maddr, sizeof (struct ipv6_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); +#else + (void) fd; + (void) addr; + THROW_NO_IPV6(env); +#endif /* HAVE_INET6 */ +#else + (void) fd; + (void) addr; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: leave + * Signature: (I[B)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_leave (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jbyteArray addr) +{ +#ifdef HAVE_SETSOCKOPT + struct ip_mreq maddr; + jbyte *addr_elems; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems); + maddr.imr_interface.s_addr = INADDR_ANY; + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, + &maddr, sizeof (struct ip_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); +#else + (void) fd; + (void) addr; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: leave6 + * Signature: (I[B)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_leave6 (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jbyteArray addr) +{ +#ifdef HAVE_SETSOCKOPT +#ifdef HAVE_INET6 + struct ipv6_mreq maddr; + jbyte *addr_elems; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16); + maddr.ipv6mr_interface = 0; + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, + &maddr, sizeof (struct ipv6_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); +#else + (void) fd; + (void) addr; + THROW_NO_IPV6(env); +#endif /* HAVE_INET6 */ +#else + (void) fd; + (void) addr; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + +static uint32_t getif_address (JNIEnv *env, const char *ifname); +static int getif_index (JNIEnv *env, const char *ifname); + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: joinGroup + * Signature: (I[BILjava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_joinGroup (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jbyteArray addr, + jstring ifname) +{ +#ifdef HAVE_SETSOCKOPT + struct ip_mreq maddr; + jbyte *addr_elems; + const char *str_ifname; + + if (ifname != NULL) + { + str_ifname = JCL_jstring_to_cstring(env, ifname); + maddr.imr_interface.s_addr = getif_address (env, str_ifname); + JCL_free_cstring(env, ifname, str_ifname); + + if ((*env)->ExceptionCheck (env)) + return; + } + else + maddr.imr_interface.s_addr = INADDR_ANY; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems); + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &maddr, sizeof (struct ip_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); + +#else + (void) fd; + (void) addr; + (void) ifname; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: joinGroup6 + * Signature: (I[BILjava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_joinGroup6 (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jbyteArray addr, + jstring ifname) +{ +#ifdef HAVE_SETSOCKOPT +#ifdef HAVE_INET6 + struct ipv6_mreq maddr; + jbyte *addr_elems; + const char *str_ifname; + + if (ifname == NULL) + { + str_ifname = JCL_jstring_to_cstring(env, ifname); + maddr.ipv6mr_interface = getif_index (env, str_ifname); + JCL_free_cstring(env, ifname, str_ifname); + + if ((*env)->ExceptionCheck (env)) + return; + } + else + maddr.ipv6mr_interface = 0; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16); + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &maddr, sizeof (struct ipv6_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); +#else + (void) fd; + (void) addr; + THROW_NO_IPV6(env); +#endif /* HAVE_INET6 */ +#else + (void) fd; + (void) addr; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: leaveGroup + * Signature: (I[BILjava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_leaveGroup (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jbyteArray addr, + jstring ifname) +{ +#ifdef HAVE_SETSOCKOPT + struct ip_mreq maddr; + jbyte *addr_elems; + const char *str_ifname; + + if (ifname != NULL) + { + str_ifname = JCL_jstring_to_cstring(env, ifname); + maddr.imr_interface.s_addr = getif_address (env, str_ifname); + JCL_free_cstring(env, ifname, str_ifname); + + if ((*env)->ExceptionCheck (env)) + return; + } + else + maddr.imr_interface.s_addr = INADDR_ANY; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems); + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, + &maddr, sizeof (struct ip_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); +#else + (void) fd; + (void) addr; + (void) ifname; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + +/* + * Class: gnu_java_net_VMPlainSocketImpl + * Method: leaveGroup6 + * Signature: (I[BILjava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_gnu_java_net_VMPlainSocketImpl_leaveGroup6 (JNIEnv *env, + jclass c __attribute__((unused)), + jint fd, jbyteArray addr, + jstring ifname) +{ +#ifdef HAVE_SETSOCKOPT +#ifdef HAVE_INET6 + struct ipv6_mreq maddr; + jbyte *addr_elems; + const char *str_ifname; + + if (ifname == NULL) + { + str_ifname = JCL_jstring_to_cstring(env, ifname); + maddr.ipv6mr_interface = getif_index (env, str_ifname); + JCL_free_cstring(env, ifname, str_ifname); + + if ((*env)->ExceptionCheck (env)) + return; + } + else + maddr.ipv6mr_interface = 0; + + addr_elems = (*env)->GetByteArrayElements (env, addr, NULL); + if (addr_elems == NULL) + return; + + memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16); + + (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT); + + if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, + &maddr, sizeof (struct ipv6_mreq))) + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); +#else + (void) fd; + (void) addr; + THROW_NO_IPV6(env); +#endif /* HAVE_INET6 */ +#else + (void) fd; + (void) addr; + JCL_ThrowException (env, "java/lang/InternalError", + "socket options not supported"); +#endif /* HAVE_SETSOCKOPT */ +} + +static uint32_t +getif_address (JNIEnv *env, const char *ifname) +{ +#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS) + struct ifaddrs *ifaddrs, *i; + uint32_t addr = 0; + int foundaddr = 0; + + if (getifaddrs (&ifaddrs) == -1) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); + return 0; + } + + for (i = ifaddrs; i != NULL; i = i->ifa_next) + { + if (strcmp (ifname, i->ifa_name) == 0) + { + /* Matched the name; see if there is an IPv4 address. */ + if (i->ifa_addr->sa_family == AF_INET) + { + foundaddr = 1; + addr = ((struct sockaddr_in *) i->ifa_addr)->sin_addr.s_addr; + break; + } + } + } + + if (!foundaddr) + JCL_ThrowException (env, SOCKET_EXCEPTION, "interface has no IPv4 address"); + + freeifaddrs (ifaddrs); + + return addr; +#else + (void) ifname; + JCL_ThrowException (env, "java/lang/InternalError", + "getifaddrs not available"); + return 0; +#endif /* HAVE_IFADDRS_H && HAVE_GETIFADDRS */ +} + +static int +getif_index (JNIEnv *env, const char *ifname) +{ +#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS) + struct ifaddrs *ifaddrs, *i; + char *lastname = NULL; + int index = 1; + int foundname = 0; + + if (getifaddrs (&ifaddrs) == -1) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno)); + return -1; + } + + lastname = ifaddrs->ifa_name; + for (i = ifaddrs; i != NULL; i = i->ifa_next) + { + if (strcmp (lastname, ifaddrs->ifa_name) != 0) + { + lastname = ifaddrs->ifa_name; + index++; + } + if (strcmp (ifname, ifaddrs->ifa_name) == 0) + { + foundname = 1; + break; + } + } + + if (!foundname) + JCL_ThrowException (env, SOCKET_EXCEPTION, + "no interface with that name"); + + freeifaddrs (ifaddrs); + + return index; +#else + (void) ifname; + JCL_ThrowException (env, "java/lang/InternalError", + "getifaddrs not available"); + return -1; +#endif /* HAVE_GETIFADDRS */ +} diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c new file mode 100644 index 000000000..288653d51 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c @@ -0,0 +1,517 @@ +/* gnu_java_net_local_LocalSocketImpl.c -- native local socket implementation. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "config.h" + +#include + +#include +#include "local.h" + +#ifdef DEBUG +#define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg) +#else +#define TRACE(msg) +#endif + +static void +_throw (JNIEnv *env, const char *exception, const char *msg) +{ + jclass _theclass = (*env)->FindClass (env, exception); + TRACE("begin"); + if (!_theclass) + { + (*env)->FatalError (env, "exception class not found"); + } + (*env)->ThrowNew (env, _theclass, msg); + TRACE("end"); +} + +void +Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv *env, jobject this, jboolean stream) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd, created; + jclass clazz; + jint fd = (jint) local_create ((int) stream); + + TRACE("begin"); + + if (fd < 0) + { + _throw (env, "java/io/IOException", local_error ()); + return; + } + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + created = (*env)->GetFieldID (env, clazz, "created", "Z"); + if (!created) + { + return; + } + (*env)->SetIntField (env, this, socket_fd, fd); + (*env)->SetBooleanField (env, this, created, JNI_TRUE); + + TRACE("end"); +#else + (void) this; + (void) stream; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv *env, jobject this, jint backlog) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + if (local_listen (fd, (int) backlog)) + { + _throw (env, "java/io/IOException", local_error ()); + return; + } + + TRACE("end"); +#else + (void) this; + (void) backlog; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv *env, jobject this, jobject socket) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jmethodID addr_init; + jfieldID socket_fd, remote_addr, local_addr; + jclass clazz1, clazz2; + jobject remote, local; + jint fd; + char path[108]; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (*env)->GetIntField (env, this, socket_fd); + fd = (jint) local_accept ((int) fd, path); + if (fd < 0) + { + _throw (env, "java/io/IOException", local_error ()); + return; + } + + clazz2 = (*env)->FindClass (env, "gnu/java/net/local/LocalSocketAddress"); + if (!clazz2) + { + return; + } + addr_init = (*env)->GetMethodID (env, clazz2, "", "(Ljava/lang/String;)V"); + if (!addr_init) + { + return; + } + remote = (*env)->NewObject (env, clazz2, addr_init, (*env)->NewStringUTF (env, path)); + + remote_addr = (*env)->GetFieldID (env, clazz1, "remote", "Lgnu/java/net/local/LocalSocketAddress;"); + if (!remote_addr) + { + return; + } + local_addr = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;"); + if (!local_addr) + { + return; + } + local = (*env)->GetObjectField (env, this, local_addr); + (*env)->SetIntField (env, socket, socket_fd, fd); + (*env)->SetObjectField (env, socket, remote_addr, remote); + (*env)->SetObjectField (env, socket, local_addr, local); + + TRACE("end"); +#else + (void) this; + (void) socket; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +jint +Java_gnu_java_net_local_LocalSocketImpl_available +(JNIEnv *env, jobject this __attribute__((unused)), jint fd) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jint avail; + + TRACE("begin"); + + avail = (jint) local_available (fd); + if (avail < 0) + { + _throw (env, "java/io/IOException", local_error ()); + return 0; + } + + TRACE("end"); + + return avail; +#else + (void) this; + (void) fd; + _throw (env, "java/lang/Error", "support for local sockets not available"); + return -1; +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + if (local_close (fd)) + { + _throw (env, "java/io/IOException", local_error ()); + } + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID local; + jmethodID get_path; + jclass clazz1, clazz2; + jobject local_ref, path; + char *addr_path; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + local = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;"); + if (!local) + { + return; + } + local_ref = (*env)->GetObjectField (env, this, local); + clazz2 = (*env)->GetObjectClass (env, local_ref); + get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;"); + if (!get_path) + { + return; + } + path = (*env)->CallObjectMethod (env, local_ref, get_path); + addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL); + if (local_unlink (addr_path)) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path); + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_sendUrgentData (JNIEnv *env, jobject this __attribute__((unused)), jint data __attribute__((unused))) +{ + /* XXX I don't remember why I have this. Probably should just + remove. */ + (*env)->FatalError (env, "Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject) not implemented"); +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (*env)->GetIntField (env, this, socket_fd); + if (local_shutdown_input (fd)) + { + _throw (env, "java/io/IOException", local_error ()); + } + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (*env)->GetIntField (env, this, socket_fd); + if (local_shutdown_output (fd)) + { + _throw (env, "java/io/IOException", local_error ()); + } + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv *env, jobject this, jobject address) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jmethodID get_path; + jobject path; + jclass clazz1, clazz2; + const char *addr_path; + int fd; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + clazz2 = (*env)->GetObjectClass (env, address); + get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;"); + path = (*env)->CallObjectMethod (env, address, get_path); + addr_path = (*env)->GetStringUTFChars (env, (jstring) path, NULL); + if (local_bind (fd, addr_path)) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path); + + TRACE("end"); +#else + (void) this; + (void) address; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv *env, jobject this, jobject address) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jmethodID get_path; + jobject path; + jclass clazz1, clazz2; + char *addr_path; + int fd; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + clazz2 = (*env)->GetObjectClass (env, address); + get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;"); + path = (*env)->CallObjectMethod (env, address, get_path); + addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL); + if (local_connect (fd, addr_path)) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path); + + TRACE("end"); +#else + (void) this; + (void) address; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +jint +Java_gnu_java_net_local_LocalSocketImpl_read +(JNIEnv *env, jobject this __attribute__((unused)), jint fd, jbyteArray buf, + jint off, jint len) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jbyte *buffer; + jint count; + + TRACE("begin"); + + if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf)) + { + _throw (env, "java/lang/ArrayIndexOutOfBoundsException", ""); + } + + buffer = (*env)->GetByteArrayElements (env, buf, NULL); + count = (jint) local_read (fd, (void *) (buffer + off), (int) len); + if (count < 0) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseByteArrayElements (env, buf, buffer, 0); + + TRACE("end"); + + return count; +#else + (void) this; + (void) fd; + (void) buf; + (void) off; + (void) len; + _throw (env, "java/lang/Error", "support for local sockets not available"); + return -1; +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_write +(JNIEnv *env, jobject this __attribute__((unused)), jint fd, jbyteArray buf, + jint off, jint len) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jbyte *buffer; + + TRACE("begin"); + + if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf)) + { + _throw (env, "java/lang/ArrayIndexOutOfBoundsException", ""); + } + + buffer = (*env)->GetByteArrayElements (env, buf, NULL); + if (local_write (fd, (void *) (buffer + off), (int) len) < 0) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseByteArrayElements (env, buf, buffer, JNI_ABORT); + + TRACE("end"); +#else + (void) this; + (void) fd; + (void) buf; + (void) off; + (void) len; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} diff --git a/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c new file mode 100644 index 000000000..6ee7773b8 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c @@ -0,0 +1,395 @@ +/* VMInetAddress.c - Native methods for InetAddress class + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* do not move; needed here because of some macro definitions */ +#include + +#include +#include +#include + +#include +#include + +#include "cpnative.h" +#include "cpnet.h" +#include "javanet.h" + +#include "java_net_VMInetAddress.h" + +/*************************************************************************/ + +/* + * Function to return the local hostname + */ +JNIEXPORT jstring JNICALL +Java_java_net_VMInetAddress_getLocalHostname (JNIEnv * env, + jclass class + __attribute__ ((__unused__))) +{ + char hostname[256]; + int result; + jstring retval; + +#ifndef WITHOUT_NETWORK + result = cpnet_getHostname (env, hostname, sizeof (hostname)); + if (result != CPNATIVE_OK) + { + strcpy (hostname, "localhost"); + } +#else /* not WITHOUT_NETWORK */ + strcpy (hostname, "localhost"); +#endif /* not WITHOUT_NETWORK */ + + retval = (*env)->NewStringUTF (env, hostname); + + return (retval); +} + +/*************************************************************************/ + +/* + * Returns the value of the special IP address INADDR_ANY + */ +JNIEXPORT jarray JNICALL +Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env, + jclass class + __attribute__ ((__unused__))) +{ + jarray IParray; + cpnet_address *addr; + jbyte *octets; + + /* Allocate an array for the IP address */ + IParray = (*env)->NewByteArray (env, 4); + if (IParray == NULL) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jarray) NULL; + } + + /* Copy in the values */ + octets = (*env)->GetByteArrayElements (env, IParray, 0); + +#ifndef WITHOUT_NETWORK + addr = cpnet_newIPV4Address (env); + cpnet_setIPV4Any (addr); + cpnet_IPV4AddressToBytes (addr, octets); + cpnet_freeAddress (env, addr); +#else /* not WITHOUT_NETWORK */ + octets[0] = 0; + octets[1] = 0; + octets[2] = 0; + octets[3] = 0; +#endif /* not WITHOUT_NETWORK */ + + (*env)->ReleaseByteArrayElements (env, IParray, octets, 0); + + return (IParray); +} + +/*************************************************************************/ + +/* + * Function to return the canonical hostname for a given IP address passed + * in as a byte array + */ +JNIEXPORT jstring JNICALL +Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env, + jclass class + __attribute__ ((__unused__)), + jarray arr) +{ +#ifndef WITHOUT_NETWORK + jbyte *octets; + jsize len; + cpnet_address *addr; + char hostname[255]; + int result; + jstring retval; + + /* Grab the byte[] array with the IP out of the input data */ + len = (*env)->GetArrayLength (env, arr); + if (len != 4 && len != 16) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring) NULL; + } + + octets = (*env)->GetByteArrayElements (env, arr, 0); + if (!octets) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring) NULL; + } + + switch (len) + { + case 4: + addr = cpnet_newIPV4Address(env); + cpnet_bytesToIPV4Address (addr, octets); + break; +#ifdef HAVE_INET6 + case 16: + addr = cpnet_newIPV6Address(env); + cpnet_bytesToIPV6Address (addr, octets); + break; +#endif + default: + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring) NULL; + + } + + /* Release some memory */ + (*env)->ReleaseByteArrayElements (env, arr, octets, 0); + + /* Resolve the address and return the name */ + result = cpnet_getHostByAddr (env, addr, hostname, sizeof (hostname)); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, + cpnative_getErrorString (result)); + return (jstring) NULL; + } + + retval = (*env)->NewStringUTF (env, hostname); + + return (retval); +#else /* not WITHOUT_NETWORK */ + return (jstring) NULL; +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +JNIEXPORT jobjectArray JNICALL +Java_java_net_VMInetAddress_getHostByName (JNIEnv * env, + jclass class + __attribute__ ((__unused__)), + jstring host) +{ +#ifndef WITHOUT_NETWORK + const char *hostname; + cpnet_address **addresses; + jsize addresses_count; + int result; + jclass arr_class; + jobjectArray addrs; + jint i; + jbyte *octets; + jarray ret_octets; + + /* Grab the hostname string */ + hostname = (*env)->GetStringUTFChars (env, host, 0); + if (!hostname) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname"); + return (jobjectArray) NULL; + } + + result = cpnet_getHostByName (env, hostname, &addresses, &addresses_count); + if (result != CPNATIVE_OK || addresses_count == 0) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, hostname); + return (jobjectArray) NULL; + } + (*env)->ReleaseStringUTFChars (env, host, hostname); + + arr_class = (*env)->FindClass (env, "[B"); + if (!arr_class) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray) NULL; + } + + addrs = (*env)->NewObjectArray (env, addresses_count, arr_class, 0); + if (!addrs) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray) NULL; + } + + /* Now loop and copy in each address */ + for (i = 0; i < addresses_count; i++) + { + if (cpnet_isIPV4Address (addresses[i])) + { + ret_octets = (*env)->NewByteArray (env, 4); + + if (!ret_octets) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + cpnet_freeAddresses (env, addresses, addresses_count); + return (jobjectArray) NULL; + } + + octets = (*env)->GetByteArrayElements (env, ret_octets, 0); + + cpnet_IPV4AddressToBytes (addresses[i], octets); + + (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0); + + (*env)->SetObjectArrayElement (env, addrs, i, ret_octets); + } +#ifdef HAVE_INET6 + else if (cpnet_isIPV6Address (addresses[i])) + { + ret_octets = (*env)->NewByteArray (env, 16); + + if (!ret_octets) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + cpnet_freeAddresses (env, addresses, addresses_count); + return (jobjectArray) NULL; + } + + octets = (*env)->GetByteArrayElements (env, ret_octets, 0); + + cpnet_IPV6AddressToBytes (addresses[i], octets); + + (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0); + + (*env)->SetObjectArrayElement (env, addrs, i, ret_octets); + } +#endif + else + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + cpnet_freeAddresses (env, addresses, addresses_count); + return (jobjectArray) NULL; + } + } + + cpnet_freeAddresses (env, addresses, addresses_count); + + return (addrs); +#else /* not WITHOUT_NETWORK */ + return (jobjectArray) NULL; +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Return the IP address represented by a literal address. + * Will return null if the literal address is not valid. + */ +JNIEXPORT jbyteArray JNICALL +Java_java_net_VMInetAddress_aton (JNIEnv *env, + jclass class + __attribute__ ((__unused__)), + jstring host) +{ +#ifndef WITHOUT_NETWORK + const char *hostname; + cpnet_address *address; + int result; + jbyte *octets; + jbyteArray ret_octets; + + hostname = (*env)->GetStringUTFChars (env, host, 0); + if (!hostname) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname"); + return (jbyteArray) NULL; + } + + result = cpnet_aton (env, hostname, &address); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + if (address) + cpnet_freeAddress (env, address); + return (jbyteArray) NULL; + } + if (!address) + return (jbyteArray) NULL; + + if (cpnet_isIPV4Address (address)) + { + ret_octets = (jbyteArray) (*env)->NewByteArray (env, 4); + + if (!ret_octets) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + cpnet_freeAddress (env, address); + return (jbyteArray) NULL; + } + + octets = (*env)->GetByteArrayElements (env, ret_octets, 0); + + cpnet_IPV4AddressToBytes (address, octets); + + (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0); + } +#ifdef HAVE_INET6 + else if (cpnet_isIPV6Address (address)) + { + ret_octets = (jbyteArray) (*env)->NewByteArray (env, 16); + + if (!ret_octets) + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + cpnet_freeAddress (env, address); + return (jbyteArray) NULL; + } + + octets = (*env)->GetByteArrayElements (env, ret_octets, 0); + + cpnet_IPV6AddressToBytes (address, octets); + + (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0); + } +#endif + else + { + JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + cpnet_freeAddress (env, address); + return (jbyteArray) NULL; + } + + cpnet_freeAddress (env, address); + + return (ret_octets); + +#else /* not WITHOUT_NETWORK */ + return (jbyteArray) NULL; +#endif /* not WITHOUT_NETWORK */ +} + +/* end of file */ diff --git a/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c new file mode 100644 index 000000000..658299733 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c @@ -0,0 +1,399 @@ +/* VMNetworkInterface.c - Native methods for NetworkInterface class + Copyright (C) 2003, 2005, 2006, 2008 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#ifdef HAVE_CONFIG_H +#include +#endif /* HAVE_CONFIG_H */ + +#include +#include +#ifdef HAVE_IFADDRS_H +#include +#endif +#include +#include +#include +#include +#include + +#include +#include +/* Required on Solaris. */ +#include + +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif + +#include +#include + +#include +#include + +#include "java_net_VMNetworkInterface.h" + +int iff_flags(JNIEnv *, jstring, jint *); + +static jmethodID java_net_VMNetworkInterface_init; +static jmethodID java_net_VMNetworkInterface_addAddress; + +/* + * Initialize our static method ID's. + * + * Class: java_net_VMNetworkInterface + * Method: initIds + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_java_net_VMNetworkInterface_initIds (JNIEnv *env, jclass clazz) +{ + java_net_VMNetworkInterface_init = + (*env)->GetMethodID (env, clazz, "", "(Ljava/lang/String;)V"); + if (java_net_VMNetworkInterface_init == NULL) + { + if (!(*env)->ExceptionCheck (env)) + JCL_ThrowException (env, "java/lang/NoSuchMethodError", + "VMNetworkinterface.addAddress"); + return; + } + java_net_VMNetworkInterface_addAddress = + (*env)->GetMethodID (env, clazz, "addAddress", "(Ljava/nio/ByteBuffer;)V"); + if (java_net_VMNetworkInterface_addAddress == NULL) + { + if (!(*env)->ExceptionCheck (env)) + JCL_ThrowException (env, "java/lang/NoSuchMethodError", + "VMNetworkinterface.addAddress"); + } +} + +struct netif_entry +{ + char *name; + jobject netif; + int numaddrs; + struct netif_entry *next; +}; + +#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS) +static void +free_netif_list (JNIEnv *env, struct netif_entry *list) +{ + while (list != NULL) + { + struct netif_entry *e = list->next; + JCL_free (env, list); + list = e; + } +} +#endif + +/* + * Returns all local network interfaces as an array. + */ +JNIEXPORT jobjectArray JNICALL +Java_java_net_VMNetworkInterface_getVMInterfaces (JNIEnv * env, + jclass clazz UNUSED) +{ +#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS) + struct ifaddrs *ifaddrs, *i; + struct netif_entry *iflist = NULL, *e; + jobjectArray netifs; + int numifs = 0; + int k; + + if (getifaddrs (&ifaddrs) == -1) + { + JCL_ThrowException (env, "java/net/SocketException", strerror (errno)); + return NULL; + } + + for (i = ifaddrs; i != NULL; i = i->ifa_next) + { + if (iflist == NULL) + { + iflist = JCL_malloc (env, sizeof (struct netif_entry)); + if (iflist == NULL) + { + freeifaddrs (ifaddrs); + return NULL; + } + iflist->name = i->ifa_name; + iflist->numaddrs = 0; + iflist->next = NULL; + iflist->netif = (*env)->NewObject (env, clazz, java_net_VMNetworkInterface_init, + (*env)->NewStringUTF (env, i->ifa_name)); + if (iflist->netif == NULL) + { + freeifaddrs (ifaddrs); + JCL_free (env, iflist); + return NULL; + } + e = iflist; + } + else + { + struct netif_entry *p = NULL; + for (e = iflist; e != NULL; e = e->next) + { + if (strcmp (e->name, i->ifa_name) == 0) + break; + p = e; + } + + if (e == NULL) + { + p->next = (struct netif_entry *) JCL_malloc (env, sizeof (struct netif_entry)); + if (p->next == NULL) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + e = p->next; + e->name = i->ifa_name; + e->numaddrs = 0; + e->next = NULL; + e->netif = (*env)->NewObject (env, clazz, java_net_VMNetworkInterface_init, + (*env)->NewStringUTF (env, i->ifa_name)); + if (e->netif == NULL) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + } + } + + if (i->ifa_addr == NULL) + continue; + + if (i->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in *sin = (struct sockaddr_in *) i->ifa_addr; + jobject buffer = (*env)->NewDirectByteBuffer (env, &(sin->sin_addr.s_addr), 4); + (*env)->CallVoidMethod (env, e->netif, java_net_VMNetworkInterface_addAddress, + buffer); + if ((*env)->ExceptionCheck (env)) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + (*env)->DeleteLocalRef (env, buffer); + e->numaddrs++; + } +#ifdef HAVE_INET6 + else if (i->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6 *sin = (struct sockaddr_in6 *) i->ifa_addr; + jobject buffer = (*env)->NewDirectByteBuffer (env, &(sin->sin6_addr.s6_addr), 16); + (*env)->CallVoidMethod (env, e->netif, java_net_VMNetworkInterface_addAddress, + buffer); + if ((*env)->ExceptionCheck (env)) + { + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return NULL; + } + (*env)->DeleteLocalRef (env, buffer); + e->numaddrs++; + } +#endif /* HAVE_INET6 */ + } + + /* Count how many interfaces we have that have addresses. */ + for (e = iflist; e != NULL; e = e->next) + { + if (e->numaddrs != 0) + numifs++; + } + + netifs = (*env)->NewObjectArray (env, numifs, clazz, NULL); + k = 0; + for (e = iflist; e != NULL && k < numifs; e = e->next) + { + if (e->numaddrs != 0) + { + (*env)->SetObjectArrayElement (env, netifs, k, e->netif); + (*env)->DeleteLocalRef (env, e->netif); + k++; + } + } + + free_netif_list (env, iflist); + freeifaddrs (ifaddrs); + return netifs; +#else + JCL_ThrowException (env, "java/net/SocketException", "getifaddrs not supported"); + return NULL; +#endif /* HAVE_IFADDRS_H && HAVE_GETIFADDRS */ +} + +int iff_flags(JNIEnv *env, jstring name, jint *flags) +{ + struct ifreq iff; + const char *iff_name; + jint socket; + int error, retval; + + if ((error = cpnet_openSocketDatagram(env, &socket, AF_INET))) + { + return error; + } + + iff_name = JCL_jstring_to_cstring(env, name); + memset(&iff, 0, sizeof(iff)); + strcpy(iff.ifr_name, iff_name); + + if (ioctl(socket, SIOCGIFFLAGS, &iff) >= 0) + { + *flags = (jint) iff.ifr_flags; + + retval = 0; + } + else + { + retval = errno; + } + + cpnet_close(env, socket); + + JCL_free_cstring(env, name, iff_name); + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_isUp (JNIEnv *env, jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & (IFF_UP | IFF_RUNNING)) + ? JNI_TRUE + : JNI_FALSE; + } + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_isPointToPoint (JNIEnv *env, + jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & IFF_POINTOPOINT) ? JNI_TRUE + : JNI_FALSE; + } + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_isLoopback (JNIEnv *env, + jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & IFF_LOOPBACK) ? JNI_TRUE : JNI_FALSE; + } + + return retval; +} + +JNIEXPORT jboolean JNICALL +Java_java_net_VMNetworkInterface_supportsMulticast (JNIEnv *env, + jclass class UNUSED, + jstring name) +{ + jint flags; + int error; + jboolean retval; + + if ((error = iff_flags(env, name, &flags))) + { + JCL_ThrowException(env, "java/net/SocketException", + cpnative_getErrorString(error)); + + retval = JNI_FALSE; + } + else + { + retval = (flags & IFF_MULTICAST) ? JNI_TRUE : JNI_FALSE; + } + + return retval; +} + +/* end of file */ diff --git a/libjava/classpath/native/jni/java-net/java_net_VMURLConnection.c b/libjava/classpath/native/jni/java-net/java_net_VMURLConnection.c new file mode 100644 index 000000000..52fae0ccb --- /dev/null +++ b/libjava/classpath/native/jni/java-net/java_net_VMURLConnection.c @@ -0,0 +1,102 @@ +/* VMURLConnection.c - native bits for URLConnection + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include + +#include + +#ifdef HAVE_MAGIC_H + +#include + +static magic_t cookie; + +#endif /* HAVE_MAGIC_H */ + +void +Java_java_net_VMURLConnection_init (JNIEnv *env __attribute__ ((__unused__)), + jclass klass __attribute__ ((__unused__))) +{ +#ifdef HAVE_MAGIC_H + cookie = magic_open (MAGIC_MIME); + if (cookie == (magic_t) NULL) + return; + if (magic_load (cookie, NULL) == -1) + { + magic_close (cookie); + cookie = (magic_t) NULL; + } +#endif /* HAVE_MAGIC_H */ +} + +#ifdef HAVE_MAGIC_H +jstring +Java_java_net_VMURLConnection_guessContentTypeFromBuffer (JNIEnv *env, + jclass klass + __attribute__ ((__unused__)), + jbyteArray bytes, + jint valid) +{ + jbyte *elements; + const char *result; + + if (cookie == (magic_t) NULL) + return NULL; + + elements = (*env)->GetByteArrayElements (env, bytes, NULL); + result = magic_buffer (cookie, elements, valid); + + /* The mode we use doesn't matter, since we don't change the array. */ + (*env)->ReleaseByteArrayElements (env, bytes, elements, JNI_ABORT); + + if (result == NULL) + return NULL; + return (*env)->NewStringUTF (env, result); +#else +jstring +Java_java_net_VMURLConnection_guessContentTypeFromBuffer (JNIEnv *env + __attribute__ ((__unused__)), + jclass klass + __attribute__ ((__unused__)), + jbyteArray bytes + __attribute__ ((__unused__)), + jint valid + __attribute__ ((__unused__))) +{ + return NULL; +#endif /* HAVE_MAGIC_H */ +} diff --git a/libjava/classpath/native/jni/java-net/javanet.c b/libjava/classpath/native/jni/java-net/javanet.c new file mode 100644 index 000000000..1f093f4aa --- /dev/null +++ b/libjava/classpath/native/jni/java-net/javanet.c @@ -0,0 +1,1500 @@ +/* javanet.c - Common internal functions for the java.net package + Copyright (C) 1998, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* do not move; needed here because of some macro definitions */ +#include + +#include +#include +#include + +#include +#include + +#include "cpnative.h" +#include "cpnet.h" + +#include "javanet.h" + +#ifndef WITHOUT_NETWORK +/* Need to have some value for SO_TIMEOUT */ +#ifndef SO_TIMEOUT +#ifndef SO_RCVTIMEO +#warning Neither SO_TIMEOUT or SO_RCVTIMEO are defined! +#warning This will cause all get/setOption calls with that value to throw an exception +#else +#define SO_TIMEOUT SO_RCVTIMEO +#endif /* not SO_RCVTIMEO */ +#endif /* not SO_TIMEOUT */ +#endif /* WITHOUT_NETWORK */ + +/*************************************************************************/ + +/* + * Sets an integer field in the specified object. + */ +static void +_javanet_set_int_field (JNIEnv * env, jobject obj, + const char *class, const char *field, int val) +{ + jclass cls; + jfieldID fid; + + cls = (*env)->FindClass (env, class); + if (cls == NULL) + return; + + fid = (*env)->GetFieldID (env, cls, field, "I"); + if (fid == NULL) + return; + + (*env)->SetIntField (env, obj, fid, val); + + return; +} + +/*************************************************************************/ + +/* + * Returns the value of the specified integer instance variable field or + * -1 if an error occurs. + */ +int +_javanet_get_int_field (JNIEnv * env, jobject obj, const char *field) +{ + jclass cls = 0; + jfieldID fid; + int fd; + + DBG ("_javanet_get_int_field(): Entered _javanet_get_int_field\n"); + + cls = (*env)->GetObjectClass (env, obj); + if (cls == NULL) + return -1; + + fid = (*env)->GetFieldID (env, cls, field, "I"); + if (fid == NULL) + return -1; + DBG ("_javanet_get_int_field(): Found field id\n"); + + fd = (*env)->GetIntField (env, obj, fid); + + return fd; +} + +/*************************************************************************/ + +/* + * Creates a FileDescriptor object in the parent class. It is not used + * by this implementation, but the docs list it as a variable, so we + * need to include it. + */ +static void +_javanet_create_localfd (JNIEnv * env, jobject this, jboolean stream) +{ + jclass this_cls, fd_cls; + jfieldID fid; + jmethodID mid; + jobject fd_obj; + + DBG ("_javanet_create_localfd(): Entered _javanet_create_localfd\n"); + + /* Look up the fd field */ + if (stream) + this_cls = (*env)->FindClass(env, "java/net/SocketImpl"); + else + this_cls = (*env)->FindClass(env, "java/net/DatagramSocketImpl"); + if (this_cls == NULL) + return; + + fid = (*env)->GetFieldID (env, this_cls, "fd", "Ljava/io/FileDescriptor;"); + if (fid == NULL) + return; + + DBG ("_javanet_create_localfd(): Found fd variable\n"); + + /* Create a FileDescriptor */ + fd_cls = (*env)->FindClass (env, "java/io/FileDescriptor"); + if (fd_cls == NULL) + return; + + DBG ("_javanet_create_localfd(): Found FileDescriptor class\n"); + + mid = (*env)->GetMethodID (env, fd_cls, "", "()V"); + if (mid == NULL) + return; + + DBG ("_javanet_create_localfd(): Found FileDescriptor constructor\n"); + + fd_obj = (*env)->NewObject (env, fd_cls, mid); + if (fd_obj == NULL) + return; + + DBG ("_javanet_create_localfd(): Created FileDescriptor\n"); + + /* Now set the pointer to the new FileDescriptor */ + (*env)->SetObjectField (env, this, fid, fd_obj); + DBG ("_javanet_create_localfd(): Set fd field\n"); + + return; +} + +/*************************************************************************/ + +/* + * Returns a Boolean object with the specfied value + */ +static jobject +_javanet_create_boolean (JNIEnv * env, jboolean val) +{ + jclass cls; + jmethodID mid; + jobject obj; + + cls = (*env)->FindClass (env, "java/lang/Boolean"); + if (cls == NULL) + return NULL; + + mid = (*env)->GetMethodID (env, cls, "", "(Z)V"); + if (mid == NULL) + return NULL; + + obj = (*env)->NewObject (env, cls, mid, val); + if (obj == NULL) + return NULL; + + return obj; +} + +/*************************************************************************/ + +/* + * Returns an Integer object with the specfied value + */ +static jobject +_javanet_create_integer (JNIEnv * env, jint val) +{ + jclass cls; + jmethodID mid; + jobject obj; + + cls = (*env)->FindClass (env, "java/lang/Integer"); + if (cls == NULL) + return NULL; + + mid = (*env)->GetMethodID (env, cls, "", "(I)V"); + if (mid == NULL) + return NULL; + + obj = (*env)->NewObject (env, cls, mid, val); + if (obj == NULL) + return NULL; + + return obj; +} + +/*************************************************************************/ + +/* + * Builds an InetAddress object from a 32 bit address in host byte order + */ +jobject +_javanet_create_inetaddress (JNIEnv * env, cpnet_address *netaddr) +{ +#ifndef WITHOUT_NETWORK + jbyte octets[4]; + char buf[64]; + jclass ia_cls; + jmethodID mid; + jstring ip_str; + jobject ia; + + /* Build a string IP address */ + cpnet_IPV4AddressToBytes(netaddr, octets); + sprintf (buf, "%d.%d.%d.%d", (int) (unsigned char)octets[0], (int)(unsigned char)octets[1], (int)(unsigned char)octets[2], (int)(unsigned char)octets[3]); + DBG ("_javanet_create_inetaddress(): Created ip addr string\n"); + + /* Get an InetAddress object for this IP */ + ia_cls = (*env)->FindClass (env, "java/net/InetAddress"); + if (ia_cls == NULL) + { + return NULL; + } + + DBG ("_javanet_create_inetaddress(): Found InetAddress class\n"); + + mid = (*env)->GetStaticMethodID (env, ia_cls, "getByName", + "(Ljava/lang/String;)Ljava/net/InetAddress;"); + if (mid == NULL) + { + return NULL; + } + + DBG ("_javanet_create_inetaddress(): Found getByName method\n"); + + ip_str = (*env)->NewStringUTF (env, buf); + if (ip_str == NULL) + { + return NULL; + } + + ia = (*env)->CallStaticObjectMethod (env, ia_cls, mid, ip_str); + if (ia == NULL) + { + return NULL; + } + + DBG ("_javanet_create_inetaddress(): Called getByName method\n"); + + return ia; +#else /* not WITHOUT_NETWORK */ + return NULL; +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +static void +_javanet_set_remhost_addr (JNIEnv * env, jobject this, jobject ia) +{ + jclass this_cls; + jfieldID fid; + + /* Set the variable in the object */ + this_cls = (*env)->FindClass (env, "java/net/SocketImpl"); + if (this_cls == NULL) + return; + + fid = + (*env)->GetFieldID (env, this_cls, "address", "Ljava/net/InetAddress;"); + if (fid == NULL) + return; + + DBG ("_javanet_set_remhost_addr(): Found address field\n"); + + (*env)->SetObjectField (env, this, fid, ia); + DBG ("_javanet_set_remhost_addr(): Set field\n"); +} + +/* + * Set's the value of the "addr" field in PlainSocketImpl with a new + * InetAddress for the specified addr + */ +static void +_javanet_set_remhost (JNIEnv * env, jobject this, cpnet_address *netaddr) +{ + jobject ia; + + DBG ("_javanet_set_remhost(): Entered _javanet_set_remhost\n"); + + /* Get an InetAddress object */ + ia = _javanet_create_inetaddress (env, netaddr); + if (ia == NULL) + return; + + _javanet_set_remhost_addr (env, this, ia); +} + + +/*************************************************************************/ + +/* + * Returns an Internet address for the passed in InetAddress object + */ +cpnet_address * +_javanet_get_ip_netaddr (JNIEnv * env, jobject addr) +{ +#ifndef WITHOUT_NETWORK + jclass cls = 0; + jmethodID mid; + jarray arr = 0; + jbyte *octets; + cpnet_address *netaddr; + jint len; + + DBG ("_javanet_get_ip_netaddr(): Entered _javanet_get_ip_netaddr\n"); + + if (addr == NULL) + { + JCL_ThrowException (env, "java/lang/NullPointerException", + "Null address"); + return 0; + } + + /* Call the getAddress method on the object to retrieve the IP address */ + cls = (*env)->GetObjectClass (env, addr); + if (cls == NULL) + return 0; + + mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B"); + if (mid == NULL) + return 0; + + DBG ("_javanet_get_ip_netaddr(): Got getAddress method\n"); + + arr = (*env)->CallObjectMethod (env, addr, mid); + if (arr == NULL) + return 0; + + DBG ("_javanet_get_ip_netaddr(): Got the address\n"); + + /* Turn the IP address into a system cpnet address. + * If the length is 4 then it is an IPV4 address, if it + * is 16 then it is an IPV6 address else it is an InternError. */ + len = (*env)->GetArrayLength (env, arr); + if (len != 4 && len != 16) + { + JCL_ThrowException (env, IO_EXCEPTION, "Internal Error"); + return 0; + } + DBG ("_javanet_get_ip_netaddr(): Length ok\n"); + + octets = (*env)->GetByteArrayElements (env, arr, 0); + if (octets == NULL) + return 0; + + DBG ("_javanet_get_ip_netaddr(): Grabbed bytes\n"); + + switch (len) + { + case 4: + netaddr = cpnet_newIPV4Address(env); + cpnet_bytesToIPV4Address(netaddr, octets); + break; +#ifdef HAVE_INET6 + case 16: + netaddr = cpnet_newIPV6Address(env); + cpnet_bytesToIPV6Address(netaddr, octets); + break; +#endif + default: + /* This should not happen as we have checked before. + * But that way we shut the compiler warnings */ + JCL_ThrowException (env, IO_EXCEPTION, "Internal Error"); + return 0; + + } + + (*env)->ReleaseByteArrayElements (env, arr, octets, 0); + DBG ("_javanet_get_ip_netaddr(): Done getting addr\n"); + + return netaddr; +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Creates a new stream or datagram socket + */ +void +_javanet_create (JNIEnv * env, jobject this, jboolean stream) +{ +#ifndef WITHOUT_NETWORK + int fd; + int result; + + if (stream) + { + /* create a stream socket */ + result = cpnet_openSocketStream(env, &fd, AF_INET); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + } + else + { + /* create a datagram socket, set broadcast option */ + result = cpnet_openSocketDatagram (env, &fd, AF_INET); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + result = cpnet_setBroadcast(env, fd, 1); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + } + + if (stream) + _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl", + "native_fd", fd); + else + _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl", + "native_fd", fd); + + if ((*env)->ExceptionOccurred (env)) + { + /* Try to make sure we close the socket since close() won't work. */ + do + { + result = cpnet_close(env, fd); + if (result != CPNATIVE_OK && result != CPNATIVE_EINTR) + return; + } + while (result != CPNATIVE_OK); + return; + } + +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Close the socket. Any underlying streams will be closed by this + * action as well. + */ +void +_javanet_close (JNIEnv * env, jobject this, int stream) +{ +#ifndef WITHOUT_NETWORK + int fd; + int result; + int error = 0; + + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + return; + + if (stream) + _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl", + "native_fd", -1); + else + _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl", + "native_fd", -1); + do + { + result = cpnet_close (env, fd); + if (result != CPNATIVE_OK) + { + /* Only throw an error when a "real" error occurs. */ + if (result != CPNATIVE_EINTR && result != ENOTCONN && result != ECONNRESET && result != EBADF) + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + } + } + while (error == CPNATIVE_EINTR); + +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Connects to the specified destination. + */ +void +_javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port, + jboolean stream) +{ +#ifndef WITHOUT_NETWORK + cpnet_address *netaddr; + int fd; + int result; + cpnet_address *local_addr; + cpnet_address *remote_addr; + + DBG ("_javanet_connect(): Entered _javanet_connect\n"); + + /* Pre-process input variables */ + netaddr = _javanet_get_ip_netaddr (env, addr); + if ((*env)->ExceptionOccurred (env)) + return; + + if (port == -1) + port = 0; + + cpnet_addressSetPort(netaddr, port); + + DBG ("_javanet_connect(): Got network address\n"); + + /* Grab the real socket file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_connect(): no native file descriptor"); + return; + } + DBG ("_javanet_connect(): Got native fd\n"); + + /* Connect up */ + do + { + result = cpnet_connect (env, fd, netaddr); + if (result != CPNATIVE_OK && result != CPNATIVE_EINTR) + { + JCL_ThrowException (env, CONNECT_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + } + while (result != CPNATIVE_OK); + + DBG ("_javanet_connect(): Connected successfully\n"); + + /* Populate instance variables */ + result = cpnet_getLocalAddr (env, fd, &local_addr); + if (result != CPNATIVE_OK) + { + cpnet_freeAddress(env, netaddr); + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_close (env, fd); + return; + } + + _javanet_create_localfd (env, this, stream); + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_freeAddress(env, netaddr); + cpnet_freeAddress(env, local_addr); + cpnet_close (env, fd); + return; + } + DBG ("_javanet_connect(): Created fd\n"); + + if (stream) + _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport", + cpnet_addressGetPort(local_addr)); + else + _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl", + "localPort", cpnet_addressGetPort(local_addr)); + + cpnet_freeAddress (env, local_addr); + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_freeAddress(env, netaddr); + cpnet_close (env, fd); + return; + } + DBG ("_javanet_connect(): Set the local port\n"); + + result = cpnet_getRemoteAddr (env, fd, &remote_addr); + if (result != CPNATIVE_OK) + { + cpnet_freeAddress(env, netaddr); + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_close (env, fd); + return; + } + + if (stream) + { + if (cpnet_isAddressEqual(remote_addr, netaddr)) + { + _javanet_set_remhost_addr (env, this, addr); + } + else + { + _javanet_set_remhost (env, this, remote_addr); + } + cpnet_freeAddress(env, netaddr); + + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. + */ + cpnet_freeAddress (env, remote_addr); + cpnet_close (env, fd); + return; + } + DBG ("_javanet_connect(): Set the remote host\n"); + + _javanet_set_int_field (env, this, "java/net/SocketImpl", "port", + cpnet_addressGetPort(remote_addr)); + cpnet_freeAddress (env, remote_addr); + + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. + */ + cpnet_close (env, fd); + return; + } + DBG ("_javanet_connect(): Set the remote port\n"); + } +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * This method binds the specified address to the specified local port. + * Note that we have to set the local address and local + * port public instance variables. + */ +void +_javanet_bind (JNIEnv * env, jobject this, jobject addr, jint port, + int stream) +{ +#ifndef WITHOUT_NETWORK + jint fd; + cpnet_address *tmpaddr; + cpnet_address *local_addr; + int result; + + DBG ("_javanet_bind(): Entering native bind()\n"); + + /* Grab the real socket file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_connect(): no native file descriptor"); + return; + } + + cpnet_setReuseAddress (env, fd, 1); + + /* Get the address to connect to */ + tmpaddr = _javanet_get_ip_netaddr (env, addr); + if ((*env)->ExceptionOccurred (env)) + return; + + cpnet_addressSetPort (tmpaddr, port); + result = cpnet_bind(env, fd, tmpaddr); + cpnet_freeAddress (env, tmpaddr); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, BIND_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + DBG ("_javanet_bind(): Past bind\n"); + + /* Update instance variables, specifically the local port number */ + result = cpnet_getLocalAddr (env, fd, &local_addr); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + + if (stream) + _javanet_set_int_field (env, this, "java/net/SocketImpl", + "localport", cpnet_addressGetPort (local_addr)); + else + _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl", + "localPort", cpnet_addressGetPort (local_addr)); + DBG ("_javanet_bind(): Past update port number\n"); + + cpnet_freeAddress (env, local_addr); + + return; +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Starts listening on a socket with the specified number of pending + * connections allowed. + */ +void +_javanet_listen (JNIEnv * env, jobject this, jint queuelen) +{ +#ifndef WITHOUT_NETWORK + int fd; + int result; + + /* Get the real file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_listen(): no native file descriptor"); + return; + } + + /* Start listening */ + result = cpnet_listen (env, fd, queuelen); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + return; + } +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Accepts a new connection and assigns it to the passed in SocketImpl + * object. Note that we assume this is a PlainSocketImpl just like us + */ +void +_javanet_accept (JNIEnv * env, jobject this, jobject impl) +{ +#ifndef WITHOUT_NETWORK + int fd, newfd; + int result; + cpnet_address *remote_addr, *local_addr; + + /* Get the real file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_accept(): no native file descriptor"); + return; + } + + /* Accept the connection */ + do + { + result = cpnet_accept (env, fd, &newfd); + if (result != CPNATIVE_OK && result != CPNATIVE_EINTR) + { + if (result == ETIMEDOUT || result == EAGAIN) + JCL_ThrowException (env, "java/net/SocketTimeoutException", + "Accept operation timed out"); + else + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + } + while (result != CPNATIVE_OK); + + /* Reset the inherited timeout. */ + cpnet_setSocketTimeout (env, newfd, 0); + + /* Populate instance variables */ + _javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl", + "native_fd", newfd); + + if ((*env)->ExceptionOccurred (env)) + { + /* Try to make sure we close the socket since close() won't work. */ + do + { + result = cpnet_close (env, newfd); + if (result != CPNATIVE_OK && result != CPNATIVE_EINTR) + return; + } + while (result != CPNATIVE_OK); + return; + } + + result = cpnet_getLocalAddr (env, newfd, &local_addr); + if (result != CPNATIVE_OK) + { + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_close (env, newfd); + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + return; + } + + _javanet_create_localfd (env, impl, 1); + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_freeAddress (env, local_addr); + cpnet_close (env, newfd); + return; + } + + _javanet_set_int_field (env, impl, "java/net/SocketImpl", "localport", + cpnet_addressGetPort (local_addr)); + cpnet_freeAddress (env, local_addr); + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_close (env, newfd); + return; + } + + result = cpnet_getRemoteAddr (env, newfd, &remote_addr); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_close (env, newfd); + return; + } + + _javanet_set_remhost (env, impl, remote_addr); + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_close (env, newfd); + cpnet_freeAddress (env, remote_addr); + return; + } + + _javanet_set_int_field (env, impl, "java/net/SocketImpl", "port", + cpnet_addressGetPort (remote_addr)); + cpnet_freeAddress (env, remote_addr); + if ((*env)->ExceptionOccurred (env)) + { + /* We don't care whether this succeeds. close() will cleanup later. */ + cpnet_close (env, newfd); + return; + } +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Receives a buffer from a remote host. The args are: + * + * buf - The byte array into which the data received will be written + * offset - Offset into the byte array to start writing + * len - The number of bytes to read. + * addr - Pointer to 32 bit net address of host to receive from. If null, + * this parm is ignored. If pointing to an address of 0, the + * actual address read is stored here + * port - Pointer to the port to receive from. If null, this parm is ignored. + * If it is 0, the actual remote port received from is stored here + * + * The actual number of bytes read is returned. + */ +int +_javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset, + int len, cpnet_address **addr) +{ +#ifndef WITHOUT_NETWORK + int fd; + jbyte *p; + cpnet_address *from_addr; + jint received_bytes; + int result; + + DBG ("_javanet_recvfrom(): Entered _javanet_recvfrom\n"); + + /* Get the real file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_recvfrom(): no native file descriptor"); + return 0; + } + DBG ("_javanet_recvfrom(): Got native_fd\n"); + + /* Get a pointer to the buffer */ + p = (*env)->GetByteArrayElements (env, buf, 0); + if (p == NULL) + return 0; + + DBG ("_javanet_recvfrom(): Got buffer\n"); + + /* Read the data */ + from_addr = NULL; + do + { + if (addr != NULL) + { + result = cpnet_recvFrom (env, fd, p + offset, len, &from_addr, &received_bytes); + } + else + { + result = cpnet_recv (env, fd, p + offset, len, &received_bytes); + } + } + while (result == CPNATIVE_EINTR); + if (result != 0) + { + if (result == EAGAIN || result == ETIMEDOUT) + JCL_ThrowException (env, "java/net/SocketTimeoutException", "Receive operation timed out"); + else + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + + /* Cleanup and return. */ + (*env)->ReleaseByteArrayElements (env, buf, p, 0); + return 0; + } + + (*env)->ReleaseByteArrayElements (env, buf, p, 0); + + /* Handle return addr case */ + if (addr != NULL) + { + (*addr) = from_addr; + } + + /* zero bytes received means recv() noticed the other side orderly + closing the connection. */ + if (received_bytes == 0) + received_bytes = -1; + + return received_bytes; +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Sends a buffer to a remote host. The args are: + * + * buf - A byte array + * offset - Index into the byte array to start sendign + * len - The number of bytes to write + * addr - The 32bit address to send to (may be 0) + * port - The port number to send to (may be 0) + */ +void +_javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len, + cpnet_address *addr) +{ +#ifndef WITHOUT_NETWORK + int fd; + jbyte *p; + jint bytes_sent; + int result; + + /* Get the real file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_sendto(): no native file descriptor"); + return; + } + + /* Get a pointer to the buffer */ + p = (*env)->GetByteArrayElements (env, buf, 0); + if (p == NULL) + return; + + /* We must send all the data, so repeat till done. */ + while (len > 0) + { + /* Send the data */ + if (addr == NULL) + { + DBG ("_javanet_sendto(): Sending....\n"); + result = cpnet_send (env, fd, p + offset, len, &bytes_sent); + } + else + { + DBG ("_javanet_sendto(): Sending....\n"); + result = cpnet_sendTo (env, fd, p + offset, len, addr, &bytes_sent); + } + + if (result == EDESTADDRREQ) + { + JCL_ThrowException (env, NULL_EXCEPTION, + "Socket is not connected and no address is given"); + break; + } + + if (bytes_sent < 0) + { + if (result != CPNATIVE_EINTR) + { + JCL_ThrowException (env, IO_EXCEPTION, + cpnative_getErrorString (result)); + break; + } + } + else + { + len -= bytes_sent; + addr += bytes_sent; + } + } + + (*env)->ReleaseByteArrayElements (env, buf, p, 0); + +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Sets the specified option for a socket + */ +void +_javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val) +{ +#ifndef WITHOUT_NETWORK + int fd; + int optval; + jclass cls; + jmethodID mid; + cpnet_address * address; + int result = CPNATIVE_OK; + + /* Get the real file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option(): no native file descriptor"); + return; + } + + /* We need a class object for all cases below */ + cls = (*env)->GetObjectClass (env, val); + if (cls == NULL) + return; + + /* Process the option request */ + switch (option_id) + { + /* TCP_NODELAY case. val is a Boolean that tells us what to do */ + case SOCKOPT_TCP_NODELAY: + mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); + if (mid == NULL) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option()"); + return; + } + + /* Should be a 0 or a 1 */ + optval = (*env)->CallBooleanMethod (env, val, mid); + if ((*env)->ExceptionOccurred (env)) + return; + + result = cpnet_setSocketTCPNoDelay (env, fd, optval); + break; + + /* SO_LINGER case. If val is a boolean, then it will always be set + to false indicating disable linger, otherwise it will be an + integer that contains the linger value */ + case SOCKOPT_SO_LINGER: + mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); + if (mid) + { + /* We are disabling linger */ + result = cpnet_setLinger (env, fd, JNI_FALSE, 0); + } + else + { + /* Clear exception if thrown for failure to do method lookup + above */ + if ((*env)->ExceptionOccurred (env)) + (*env)->ExceptionClear (env); + + mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); + if (mid == NULL) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option()"); + return; + } + + optval = (*env)->CallIntMethod (env, val, mid); + if ((*env)->ExceptionOccurred (env)) + return; + + result = cpnet_setLinger(env, fd, JNI_TRUE, optval); + } + break; + + /* SO_TIMEOUT case. Val will be an integer with the new value */ + /* Not writable on Linux */ + case SOCKOPT_SO_TIMEOUT: + mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); + if (mid == NULL) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option()"); + return; + } + + optval = (*env)->CallIntMethod (env, val, mid); + if ((*env)->ExceptionOccurred (env)) + return; + + result = cpnet_setSocketTimeout (env, fd, optval); + break; + + case SOCKOPT_SO_SNDBUF: + case SOCKOPT_SO_RCVBUF: + mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); + if (mid == NULL) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option()"); + return; + } + + + optval = (*env)->CallIntMethod (env, val, mid); + if ((*env)->ExceptionOccurred (env)) + return; + + if (option_id == SOCKOPT_SO_SNDBUF) + result = cpnet_setSendBuf (env, fd, optval); + else + result = cpnet_setRecvBuf (env, fd, optval); + break; + + /* TTL case. Val with be an Integer with the new time to live value */ + case SOCKOPT_IP_TTL: + mid = (*env)->GetMethodID (env, cls, "intValue", "()I"); + if (!mid) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option()"); + return; + } + + optval = (*env)->CallIntMethod (env, val, mid); + if ((*env)->ExceptionOccurred (env)) + return; + + result = cpnet_setTTL (env, fd, optval); + break; + + /* Multicast Interface case - val is InetAddress object */ + case SOCKOPT_IP_MULTICAST_IF: + address = _javanet_get_ip_netaddr (env, val); + + if ((*env)->ExceptionOccurred (env)) + return; + + result = cpnet_setMulticastIF (env, fd, address); + cpnet_freeAddress (env, address); + break; + + case SOCKOPT_SO_REUSEADDR: + mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); + if (mid == NULL) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option()"); + return; + } + + /* Should be a 0 or a 1 */ + optval = (*env)->CallBooleanMethod (env, val, mid); + if ((*env)->ExceptionOccurred (env)) + return; + + result = cpnet_setReuseAddress (env, fd, optval); + break; + + case SOCKOPT_SO_KEEPALIVE: + mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z"); + if (mid == NULL) + { + JCL_ThrowException (env, IO_EXCEPTION, + "Internal error: _javanet_set_option()"); + return; + } + + /* Should be a 0 or a 1 */ + optval = (*env)->CallBooleanMethod (env, val, mid); + if ((*env)->ExceptionOccurred (env)) + return; + + result = cpnet_setKeepAlive (env, fd, optval); + break; + + case SOCKOPT_SO_BINDADDR: + JCL_ThrowException (env, SOCKET_EXCEPTION, "This option cannot be set"); + break; + + default: + JCL_ThrowException (env, SOCKET_EXCEPTION, "Unrecognized option"); + return; + } + + /* Check to see if above operations succeeded */ + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return; + } +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +/* + * Retrieves the specified option values for a socket + */ +jobject +_javanet_get_option (JNIEnv * env, jobject this, jint option_id) +{ +#ifndef WITHOUT_NETWORK + int fd; + int flag, optval; + cpnet_address *address; + int result; + jobject obj; + + /* Get the real file descriptor */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + "Internal error: _javanet_get_option(): no native file descriptor"); + return (0); + } + + /* Process the option requested */ + switch (option_id) + { + /* TCP_NODELAY case. Return a Boolean indicating on or off */ + case SOCKOPT_TCP_NODELAY: + result = cpnet_getSocketTCPNoDelay (env, fd, &optval); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + if (optval) + return (_javanet_create_boolean (env, JNI_TRUE)); + else + return (_javanet_create_boolean (env, JNI_FALSE)); + + break; + + /* SO_LINGER case. If disabled, return a Boolean object that represents + false, else return an Integer that is the value of SO_LINGER */ + case SOCKOPT_SO_LINGER: + result = cpnet_getLinger (env, fd, &flag, &optval); + + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + if (flag) + return (_javanet_create_integer (env, optval)); + else + return (_javanet_create_boolean (env, JNI_FALSE)); + + break; + + /* SO_TIMEOUT case. Return an Integer object with the timeout value */ + case SOCKOPT_SO_TIMEOUT: + result = cpnet_getSocketTimeout (env, fd, &optval); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + return (_javanet_create_integer (env, optval)); + break; + + case SOCKOPT_SO_SNDBUF: + case SOCKOPT_SO_RCVBUF: + if (option_id == SOCKOPT_SO_SNDBUF) + result = cpnet_getSendBuf (env, fd, &optval); + else + result = cpnet_getRecvBuf (env, fd, &optval); + + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + return (_javanet_create_integer (env, optval)); + break; + + /* The TTL case. Return an Integer with the Time to Live value */ + case SOCKOPT_IP_TTL: + result = cpnet_getTTL (env, fd, &optval); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + return (_javanet_create_integer (env, optval)); + break; + + /* Multicast interface case */ + case SOCKOPT_IP_MULTICAST_IF: + result = cpnet_getMulticastIF (env, fd, &address); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + obj = _javanet_create_inetaddress (env, address); + cpnet_freeAddress (env, address); + + return obj; + break; + + case SOCKOPT_SO_BINDADDR: + result = cpnet_getLocalAddr (env, fd, &address); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + obj = _javanet_create_inetaddress (env, address); + cpnet_freeAddress (env, address); + + return obj; + break; + + case SOCKOPT_SO_REUSEADDR: + result = cpnet_getReuseAddress (env, fd, &optval); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + if (optval) + return _javanet_create_boolean (env, JNI_TRUE); + else + return _javanet_create_boolean (env, JNI_FALSE); + + break; + + case SOCKOPT_SO_KEEPALIVE: + result = cpnet_getKeepAlive (env, fd, &optval); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return (0); + } + + if (optval) + return _javanet_create_boolean (env, JNI_TRUE); + else + return _javanet_create_boolean (env, JNI_FALSE); + + break; + + default: + JCL_ThrowException (env, SOCKET_EXCEPTION, "No such option"); + return (0); + } + + return (0); +#else /* not WITHOUT_NETWORK */ +#endif /* not WITHOUT_NETWORK */ +} + +void +_javanet_shutdownInput (JNIEnv * env, jobject this) +{ + int result; + int fd; + + /* Get the real file descriptor. */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + "Internal error: _javanet_get_option(): no native file descriptor"); + return; + } + + /* Shutdown input stream of socket. */ + result = cpnet_shutdown (env, fd, CPNET_SHUTDOWN_READ); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return; + } +} + +void +_javanet_shutdownOutput (JNIEnv * env, jobject this) +{ + int fd; + int result; + + /* Get the real file descriptor. */ + fd = _javanet_get_int_field (env, this, "native_fd"); + if (fd == -1) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + "Internal error: _javanet_get_option(): no native file descriptor"); + return; + } + + /* Shutdown output stream of socket. */ + result = cpnet_shutdown (env, fd, CPNET_SHUTDOWN_WRITE); + if (result != CPNATIVE_OK) + { + JCL_ThrowException (env, SOCKET_EXCEPTION, + cpnative_getErrorString (result)); + return; + } +} + +/* end of file */ diff --git a/libjava/classpath/native/jni/java-net/javanet.h b/libjava/classpath/native/jni/java-net/javanet.h new file mode 100644 index 000000000..96dba881b --- /dev/null +++ b/libjava/classpath/native/jni/java-net/javanet.h @@ -0,0 +1,101 @@ +/* javanet.h - Declarations for common functions for the java.net package + Copyright (C) 1998, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +#ifndef _JAVANET_LOADED +#define _JAVANET_LOADED + +#include +#include "jcl.h" +#include "cpnet.h" + +/*************************************************************************/ + +/* + * Defined constants + */ + +/* Exception Classes */ +#define BIND_EXCEPTION "java/net/BindException" +#define IO_EXCEPTION "java/io/IOException" +#define CONNECT_EXCEPTION "java/net/ConnectException" +#define SOCKET_EXCEPTION "java/net/SocketException" +#define UNKNOWN_HOST_EXCEPTION "java/net/UnknownHostException" +#define NULL_EXCEPTION "java/lang/NullPointerException" + +/* Socket Option Identifiers - Don't change or binary compatibility with + the JDK will be broken! These also need to + be kept compatible with java.net.SocketOptions */ +#define SOCKOPT_TCP_NODELAY 1 +#define SOCKOPT_SO_BINDADDR 15 +#define SOCKOPT_SO_LINGER 128 +#define SOCKOPT_SO_TIMEOUT 4102 +#define SOCKOPT_SO_SNDBUF 4097 +#define SOCKOPT_SO_RCVBUF 4098 +#define SOCKOPT_SO_REUSEADDR 4 +#define SOCKOPT_IP_MULTICAST_IF 16 +#define SOCKOPT_SO_KEEPALIVE 8 + +/* Internal option identifiers. Not needed for JDK compatibility */ +#define SOCKOPT_IP_TTL 7777 + +/*************************************************************************/ + +/* + * Function Prototypes + */ + +extern int _javanet_get_int_field(JNIEnv *, jobject, const char *); +extern cpnet_address *_javanet_get_ip_netaddr(JNIEnv *, jobject); +extern jobject _javanet_create_inetaddress (JNIEnv *, cpnet_address *); +extern void _javanet_create(JNIEnv *, jobject, jboolean); +extern void _javanet_close(JNIEnv *, jobject, int); +extern void _javanet_connect(JNIEnv *, jobject, jobject, jint, jboolean); +extern void _javanet_bind(JNIEnv *, jobject, jobject, jint, int); +extern void _javanet_listen(JNIEnv *, jobject, jint); +extern void _javanet_accept(JNIEnv *, jobject, jobject); +extern int _javanet_recvfrom(JNIEnv *, jobject, jarray, int, int, cpnet_address **); +extern void _javanet_sendto(JNIEnv *, jobject, jarray, int, int, cpnet_address *); +extern jobject _javanet_get_option(JNIEnv *, jobject, jint); +extern void _javanet_set_option(JNIEnv *, jobject, jint, jobject); +extern void _javanet_shutdownInput (JNIEnv *, jobject); +extern void _javanet_shutdownOutput (JNIEnv *, jobject); + +/*************************************************************************/ + +#endif /* not _JAVANET_H_LOADED */ + diff --git a/libjava/classpath/native/jni/java-net/local.c b/libjava/classpath/native/jni/java-net/local.c new file mode 100644 index 000000000..53830f371 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/local.c @@ -0,0 +1,189 @@ +/* local.c -- implementation of unix-domain sockets. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +#include "config.h" + +#ifdef ENABLE_LOCAL_SOCKETS + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(HAVE_SYS_IOCTL_H) +#define BSD_COMP /* Get FIONREAD on Solaris2 */ +#include +#endif +#if defined(HAVE_SYS_FILIO_H) /* Get FIONREAD on Solaris 2.5 */ +#include +#endif + +#include "local.h" + +const char * +local_error (void) +{ + return strerror (errno); +} + +int +local_create (int stream) +{ + return socket (PF_UNIX, stream ? SOCK_STREAM : SOCK_DGRAM, 0); +} + +int +local_bind (int fd, const char *addr) +{ + struct sockaddr_un saddr; + + if (strlen (addr) >= sizeof (saddr.sun_path)) + { + errno = ENAMETOOLONG; + return -1; + } + + strcpy (saddr.sun_path, addr); + saddr.sun_family = AF_LOCAL; + + return bind (fd, (struct sockaddr *) &saddr, SUN_LEN (&saddr)); +} + +int +local_listen (int fd, int backlog) +{ + return listen (fd, backlog); +} + +int +local_accept (int fd, char *path) +{ + int newfd; + struct sockaddr_un addr; + socklen_t sz = SUN_LEN(&addr); + + newfd = accept (fd, (struct sockaddr *) &addr, &sz); + if (newfd >= 0) + { + /** sun_path is some crazy statically-sized buffer, and it's + size is different on different OSes. */ + int n = sizeof (addr.sun_path); + strncpy (path, addr.sun_path, n); + path[n] = '\0'; + } + return newfd; +} + +int +local_available (int fd) +{ + int val; + if (ioctl (fd, FIONREAD, &val)) + { + return -1; + } + return val; +} + +int +local_close (int fd) +{ + return close (fd); +} + +int +local_unlink (char *path) +{ + return unlink (path); +} + +int +local_shutdown_input (int fd) +{ + return shutdown (fd, 0); +} + +int +local_shutdown_output (int fd) +{ + return shutdown (fd, 1); +} + +int +local_connect (int fd, char *path) +{ + struct sockaddr_un saddr; + + strncpy (saddr.sun_path, path, sizeof (saddr.sun_path)); + saddr.sun_path[sizeof (saddr.sun_path) - 1] = '\0'; + saddr.sun_family = AF_UNIX; + + return connect (fd, (struct sockaddr *) &saddr, SUN_LEN(&saddr)); +} + +int +local_read (int fd, void *buf, int len) +{ + int count = -1; + do + { + count = read (fd, buf, len); + } + while (count == -1 && errno == EINTR); + return count; +} + +int +local_write (int fd, void *buf, int len) +{ + int count = -1; + do + { + count = write (fd, buf, len); + } + while (count == -1 && errno == EINTR); + return count; +} + +#endif /* ENABLE_LOCAL_SOCKETS */ diff --git a/libjava/classpath/native/jni/java-net/local.h b/libjava/classpath/native/jni/java-net/local.h new file mode 100644 index 000000000..035996a80 --- /dev/null +++ b/libjava/classpath/native/jni/java-net/local.h @@ -0,0 +1,28 @@ +#ifndef __LOCAL_H__ +#define __LOCAL_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif +#define __EMACSEN__ } + +extern const char *local_error (void); +extern int local_create (int); +extern int local_bind (int, const char *); +extern int local_listen (int, int); +extern int local_accept (int, char *); +extern int local_available (int); +extern int local_close (int); +extern int local_shutdown_input (int); +extern int local_shutdown_output (int); +extern int local_connect (int, char *); +extern int local_unlink (char *); +extern int local_read (int, void *, int); +extern int local_write (int, void *, int); + +#ifdef __cplusplus +} +#endif + +#endif /* __LOCAL_H__ */ -- cgit v1.2.3