summaryrefslogtreecommitdiff
path: root/libjava/classpath/native/jni/java-nio
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/native/jni/java-nio')
-rw-r--r--libjava/classpath/native/jni/java-nio/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/java-nio/Makefile.am24
-rw-r--r--libjava/classpath/native/jni/java-nio/Makefile.in642
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c416
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_KqueueSelectorImpl.c387
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c2035
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c83
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c303
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c208
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c208
-rw-r--r--libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c241
-rw-r--r--libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c130
-rw-r--r--libjava/classpath/native/jni/java-nio/javanio.c144
-rw-r--r--libjava/classpath/native/jni/java-nio/javanio.h334
14 files changed, 5163 insertions, 0 deletions
diff --git a/libjava/classpath/native/jni/java-nio/.cvsignore b/libjava/classpath/native/jni/java-nio/.cvsignore
new file mode 100644
index 000000000..e9f2658a6
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/java-nio/Makefile.am b/libjava/classpath/native/jni/java-nio/Makefile.am
new file mode 100644
index 000000000..398e6a6e7
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/Makefile.am
@@ -0,0 +1,24 @@
+nativeexeclib_LTLIBRARIES = libjavanio.la
+
+libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \
+ gnu_java_nio_VMChannel.c \
+ gnu_java_nio_VMSelector.c \
+ gnu_java_nio_charset_iconv_IconvDecoder.c \
+ gnu_java_nio_charset_iconv_IconvEncoder.c \
+ java_nio_MappedByteBufferImpl.c \
+ java_nio_VMDirectByteBuffer.c \
+ gnu_java_nio_EpollSelectorImpl.c \
+ gnu_java_nio_KqueueSelectorImpl.c \
+ javanio.h
+
+libjavanio_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la \
+ $(LTLIBICONV)
+
+# Directly included through javanio.h
+EXTRA_DIST = javanio.c
+
+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-nio/Makefile.in b/libjava/classpath/native/jni/java-nio/Makefile.in
new file mode 100644
index 000000000..427d072a1
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/Makefile.in
@@ -0,0 +1,642 @@
+# 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-nio
+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 =
+libjavanio_la_DEPENDENCIES = \
+ $(top_builddir)/native/jni/classpath/jcl.lo \
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la \
+ $(am__DEPENDENCIES_1)
+am_libjavanio_la_OBJECTS = gnu_java_nio_VMPipe.lo \
+ gnu_java_nio_VMChannel.lo gnu_java_nio_VMSelector.lo \
+ gnu_java_nio_charset_iconv_IconvDecoder.lo \
+ gnu_java_nio_charset_iconv_IconvEncoder.lo \
+ java_nio_MappedByteBufferImpl.lo \
+ java_nio_VMDirectByteBuffer.lo \
+ gnu_java_nio_EpollSelectorImpl.lo \
+ gnu_java_nio_KqueueSelectorImpl.lo
+libjavanio_la_OBJECTS = $(am_libjavanio_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 = $(libjavanio_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 = libjavanio.la
+libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \
+ gnu_java_nio_VMChannel.c \
+ gnu_java_nio_VMSelector.c \
+ gnu_java_nio_charset_iconv_IconvDecoder.c \
+ gnu_java_nio_charset_iconv_IconvEncoder.c \
+ java_nio_MappedByteBufferImpl.c \
+ java_nio_VMDirectByteBuffer.c \
+ gnu_java_nio_EpollSelectorImpl.c \
+ gnu_java_nio_KqueueSelectorImpl.c \
+ javanio.h
+
+libjavanio_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la \
+ $(LTLIBICONV)
+
+
+# Directly included through javanio.h
+EXTRA_DIST = javanio.c
+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-nio/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu native/jni/java-nio/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
+libjavanio.la: $(libjavanio_la_OBJECTS) $(libjavanio_la_DEPENDENCIES)
+ $(LINK) -rpath $(nativeexeclibdir) $(libjavanio_la_OBJECTS) $(libjavanio_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_nio_EpollSelectorImpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_nio_KqueueSelectorImpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_nio_VMChannel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_nio_VMPipe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_nio_VMSelector.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_nio_charset_iconv_IconvDecoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_nio_charset_iconv_IconvEncoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_nio_MappedByteBufferImpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_nio_VMDirectByteBuffer.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-nio/gnu_java_nio_EpollSelectorImpl.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c
new file mode 100644
index 000000000..39161d68e
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c
@@ -0,0 +1,416 @@
+/* gnu_java_nio_EpollSelectorImpl.c --
+ 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. */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_SYS_EPOLL_H
+#include <sys/epoll.h>
+#endif /* HAVE_SYS_EPOLL_H */
+
+#include <config-int.h>
+
+#include <gnu_java_nio_EpollSelectorImpl.h>
+#include <jcl.h>
+#include <errno.h>
+#include <string.h>
+
+#define IO_EXCEPTION "java/io/IOException"
+
+/* #define TRACE_EPOLL 1 */
+
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: epoll_supported
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_epoll_1supported (JNIEnv *e __attribute__((unused)),
+ jclass c __attribute__((unused)))
+{
+#ifdef HAVE_EPOLL_CREATE
+ return JNI_TRUE;
+#else
+ return JNI_FALSE;
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: sizeof_struct
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_sizeof_1struct (JNIEnv *env,
+ jclass c __attribute__((unused)))
+{
+#ifdef HAVE_EPOLL_CREATE
+ (void) env;
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: sizeof is %d\n", __FUNCTION__, sizeof (struct epoll_event));
+#endif /* TRACE_EPOLL */
+ return sizeof (struct epoll_event);
+#else
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+ return -1;
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: epoll_create
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_epoll_1create (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint size)
+{
+#ifdef HAVE_EPOLL_CREATE
+ int fd = epoll_create (size);
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: epoll_create returns %d\n", __FUNCTION__, fd);
+#endif /* TRACE_EPOLL */
+
+ if (fd == -1)
+ {
+ if (ENOSYS == errno)
+ JCL_ThrowException (env, "java/lang/InternalError",
+ strerror (errno));
+ else
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+ return fd;
+#else
+ (void) size;
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+ return -1;
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: epoll_add
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_epoll_1add (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint efd, jint fd, jint ops)
+{
+#ifdef HAVE_EPOLL_CREATE
+ struct epoll_event event;
+
+ memset (&event, 0, sizeof (struct epoll_event));
+
+ if ((ops & gnu_java_nio_EpollSelectorImpl_OP_ACCEPT) != 0
+ || (ops & gnu_java_nio_EpollSelectorImpl_OP_READ) != 0)
+ event.events = EPOLLIN;
+
+ if ((ops & gnu_java_nio_EpollSelectorImpl_OP_CONNECT) != 0
+ || (ops & gnu_java_nio_EpollSelectorImpl_OP_WRITE) != 0)
+ event.events |= EPOLLOUT;
+
+ event.data.fd = fd;
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: adding struct epoll_event { events: %o; data.fd: %d } to %d\n",
+ __FUNCTION__, event.events, event.data.fd, efd);
+#endif /* TRACE_EPOLL */
+
+ if (epoll_ctl (efd, EPOLL_CTL_ADD, fd, &event) == -1)
+ {
+ if (ENOSYS == errno)
+ JCL_ThrowException (env, "java/lang/InternalError",
+ strerror (errno));
+ else
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+#else
+ (void) efd;
+ (void) fd;
+ (void) ops;
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: epoll_modify
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_epoll_1modify (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint efd, jint fd, jint ops)
+{
+#ifdef HAVE_EPOLL_CREATE
+ struct epoll_event event;
+
+ memset (&event, 0, sizeof (struct epoll_event));
+
+ if ((ops & gnu_java_nio_EpollSelectorImpl_OP_ACCEPT) != 0
+ || (ops & gnu_java_nio_EpollSelectorImpl_OP_READ) != 0)
+ event.events = EPOLLIN;
+
+ if ((ops & gnu_java_nio_EpollSelectorImpl_OP_CONNECT) != 0
+ || (ops & gnu_java_nio_EpollSelectorImpl_OP_WRITE) != 0)
+ event.events |= EPOLLOUT;
+
+ event.data.fd = fd;
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: modding struct epoll_event { events: %o; data.fd: %d } on %d\n",
+ __FUNCTION__, event.events, event.data.fd, efd);
+#endif /* TRACE_EPOLL */
+
+ if (epoll_ctl (efd, EPOLL_CTL_MOD, fd, &event) == -1)
+ {
+ if (ENOSYS == errno)
+ JCL_ThrowException (env, "java/lang/InternalError",
+ strerror (errno));
+ else
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+#else
+ (void) efd;
+ (void) fd;
+ (void) ops;
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: epoll_delete
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_epoll_1delete (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint efd, jint fd)
+{
+#ifdef HAVE_EPOLL_CREATE
+ struct epoll_event event;
+
+ memset (&event, 0, sizeof (struct epoll_event));
+ event.data.fd = fd;
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: delete events on fd %d for %d\n", __FUNCTION__, fd, efd);
+#endif /* TRACE_EPOLL */
+
+ /* Older kernel versions require a non-null `event' parameter,
+ * even though it is ignored by this call.
+ */
+ if (epoll_ctl (efd, EPOLL_CTL_DEL, fd, &event) == -1)
+ {
+ if (ENOSYS == errno)
+ JCL_ThrowException (env, "java/lang/InternalError",
+ strerror (errno));
+ /* XXX the docs here seem a little strange. If `fd' is closed,
+ epoll_ctl returns EBADF; but the docs say that this happens
+ only when efd is invalid. Go figure.
+ */
+ else if (ENOENT == errno || EBADF == errno)
+ return; /* fd is closed; it's already removed. */
+ else
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+#else
+ (void) efd;
+ (void) fd;
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: epoll_wait
+ * Signature: (ILjava/nio/ByteBuffer;II)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_epoll_1wait (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint efd, jobject nstate,
+ jint num_events, jint timeout)
+{
+#ifdef HAVE_EPOLL_CREATE
+ void *p = (*env)->GetDirectBufferAddress (env, nstate);
+ struct epoll_event *events = (struct epoll_event *) p;
+ int ret;
+
+ if (p == NULL)
+ {
+ if (!(*env)->ExceptionCheck (env))
+ JCL_ThrowException (env, IO_EXCEPTION, "getting native state failed");
+ return -1;
+ }
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: events: %p; num_events: %d; timeout: %d; efd: %d\n",
+ __FUNCTION__, p, num_events, timeout, efd);
+#endif /* TRACE_EPOLL */
+
+ ret = epoll_wait (efd, events, num_events, timeout);
+
+ if (ret == -1)
+ {
+ if (ENOSYS == errno)
+ JCL_ThrowException (env, "java/lang/InternalError",
+ strerror (errno));
+ else if (EINTR == errno)
+ ret = 0;
+ else
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, " epoll_wait returns %d\n", ret);
+ {
+ int i;
+ for (i = 0; i < ret; i++)
+ {
+ fprintf (stderr, " [%4i]: events: %o; data.fd: %d\n", i, events[i].events,
+ events[i].data.fd);
+ }
+ }
+ fflush (stderr);
+#endif /* TRACE_EPOLL */
+
+ return ret;
+#else
+ (void) efd;
+ (void) nstate;
+ (void) num_events;
+ (void) timeout;
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+ return -1;
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: selected_fd
+ * Signature: (Ljava/nio/ByteBuffer;)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_selected_1fd (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jobject value)
+{
+#ifdef HAVE_EPOLL_CREATE
+ void *p = (*env)->GetDirectBufferAddress (env, value);
+ struct epoll_event *event = (struct epoll_event *) p;
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: event: %p\n", __FUNCTION__, p);
+#endif /* TRACE_EPOLL */
+
+ if (p == NULL)
+ {
+ if (!(*env)->ExceptionCheck (env))
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "getting native state failed");
+ return -1;
+ }
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, " data.fd: %d\n", event->data.fd);
+ fflush (stderr);
+#endif /* TRACE_EPOLL */
+
+ return event->data.fd;
+#else
+ (void) value;
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+ return -1;
+#endif /* HAVE_EPOLL_CREATE */
+}
+
+
+/*
+ * Class: gnu_java_nio_EpollSelectorImpl
+ * Method: selected_ops
+ * Signature: (Ljava/nio/ByteBuffer;)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_EpollSelectorImpl_selected_1ops (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jobject value)
+{
+#ifdef HAVE_EPOLL_CREATE
+ void *p = (*env)->GetDirectBufferAddress (env, value);
+ struct epoll_event *event = (struct epoll_event *) p;
+ int ret = 0;
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, "%s: event: %p\n", __FUNCTION__, p);
+#endif /* TRACE_EPOLL */
+
+ if (p == NULL)
+ {
+ if (!(*env)->ExceptionCheck (env))
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "getting native state failed");
+ return -1;
+ }
+
+ if ((event->events & EPOLLIN) != 0)
+ ret |= gnu_java_nio_EpollSelectorImpl_OP_ACCEPT | gnu_java_nio_EpollSelectorImpl_OP_READ;
+ if ((event->events & EPOLLOUT) != 0)
+ ret |= gnu_java_nio_EpollSelectorImpl_OP_CONNECT | gnu_java_nio_EpollSelectorImpl_OP_WRITE;
+
+#ifdef TRACE_EPOLL
+ fprintf (stderr, " events: %o\n", event->events);
+ fflush (stderr);
+#endif /* TRACE_EPOLL */
+
+ return ret;
+#else
+ (void) value;
+ JCL_ThrowException (env, "java/lang/InternalError", "epoll support not available");
+ return -1;
+#endif /* HAVE_EPOLL_CREATE */
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_KqueueSelectorImpl.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_KqueueSelectorImpl.c
new file mode 100644
index 000000000..94e6db7f8
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_KqueueSelectorImpl.c
@@ -0,0 +1,387 @@
+/* gnu_java_nio_channel_KqueueSelectorImpl.c --
+ 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. */
+
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <sys/types.h>
+#if HAVE_SYS_EVENT_H
+#include <sys/event.h>
+#endif /* HAVE_SYS_EVENT_H */
+#include <sys/time.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <jni.h>
+#include <gnu_java_nio_KqueueSelectorImpl.h>
+
+#include <jcl.h>
+
+#define KEY_OP_ACCEPT 16
+#define KEY_OP_CONNECT 8
+#define KEY_OP_READ 1
+#define KEY_OP_WRITE 4
+
+/* XXX this requires -std=gnu99 or c99 */
+/* #ifdef TRACE_KQUEUE */
+/* #define TRACE(fmt, ...) fprintf (stderr, "%s: " fmt "\n", __FUNCTION__, __VA_ARGS__); */
+/* #else */
+/* #define TRACE(fmt, ...) */
+/* #endif */
+
+/* #define TRACE_KQUEUE 1 */
+
+
+#define throw_not_supported(env) JCL_ThrowException (env, "java/lang/UnsupportedOperationException", "kqueue/kevent support not available")
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: kqueue_supported
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_kqueue_1supported (JNIEnv *env __attribute__((unused)),
+ jclass clazz __attribute__((unused)))
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+ return JNI_TRUE;
+#else
+ return JNI_FALSE;
+#endif /* HAVE_KQUEUE && HAVE_KEVENT */
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: sizeof_struct_kevent
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_sizeof_1struct_1kevent
+(JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+/* TRACE("return sizeof %lu", sizeof (struct kevent)); */
+ return sizeof (struct kevent);
+#else
+ throw_not_supported (env);
+ return -1;
+#endif /* HAVE_KQUEUE && HAVE_KEVENT */
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: implOpen
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_implOpen
+(JNIEnv *env, jclass clazz __attribute__((unused)))
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+ int kq = kqueue ();
+/* TRACE("kqueue returns %d", kq); */
+ if (kq == -1)
+ JCL_ThrowException (env, "java/io/IOException", strerror (errno));
+ return kq;
+#else
+ throw_not_supported (env);
+ return -1;
+#endif
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: implClose
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_implClose (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jint kq)
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+/* TRACE("closing %d", kq); */
+ if (close (kq) != 0)
+ JCL_ThrowException (env, "java/io/IOException", strerror (errno));
+#else
+ (void) kq;
+ throw_not_supported (env);
+#endif /* HAVE_KQUEUE && HAVE_KEVENT */
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: kevent_set
+ * Signature: (Ljava/nio/ByteBuffer;IIIZ)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_kevent_1set (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jobject nstate, jint i, jint fd,
+ jint ops, jint active, jint key)
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+ struct kevent *kev;
+ short ident;
+
+ kev = (struct kevent *) (*env)->GetDirectBufferAddress (env, nstate);
+
+#ifdef TRACE_KQUEUE
+ printf ("kevent_set fd:%d p:%p i:%d ops:%x active:%x key:%x\n",
+ fd, (void *) kev, i, ops, active, key);
+#endif /* TRACE_KQUEUE */
+
+ if (kev == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "GetDirectBufferAddress returned NULL!");
+ return;
+ }
+
+ ident = fd;
+ memset (&kev[i], 0, sizeof (struct kevent));
+
+ if ((ops & KEY_OP_READ) || (ops & KEY_OP_ACCEPT))
+ {
+ /* Add event if it wasn't previously added. */
+ if (!(active & KEY_OP_READ) && !(active & KEY_OP_ACCEPT))
+ EV_SET(&kev[i], ident, EVFILT_READ, EV_ADD, 0, 0, (void *) key);
+ }
+ else
+ {
+ /* Delete event if it was previously added */
+ if ((active & KEY_OP_READ) || (active & KEY_OP_ACCEPT))
+ EV_SET(&kev[i], ident, EVFILT_READ, EV_DELETE, 0, 0, (void *) key);
+ }
+
+ /* Do the same thing for the write filter. */
+ if ((ops & KEY_OP_WRITE) || (ops & KEY_OP_CONNECT))
+ {
+ if (!(active & KEY_OP_WRITE) && !(active & KEY_OP_CONNECT))
+ EV_SET(&kev[i], ident, EVFILT_WRITE, EV_ADD, 0, 0, (void *) key);
+ }
+ else
+ {
+ if ((active & KEY_OP_WRITE) || (active & KEY_OP_CONNECT))
+ EV_SET(&kev[i], ident, EVFILT_WRITE, EV_DELETE, 0, 0, (void *) key);
+ }
+
+#ifdef TRACE_KQUEUE
+ printf (" set kevent %2d: ident:%u filter:%x flags:%o fflags:%o data:%p udata:%p\n",
+ i, (unsigned) kev[i].ident, kev[i].filter, kev[i].flags, kev[i].fflags,
+ (void *) kev[i].data, kev[i].udata);
+#endif /* TRACE_KQUEUE */
+#else
+ (void) nstate;
+ (void) i;
+ (void) fd;
+ (void) ops;
+ (void) key;
+ (void) active;
+ throw_not_supported (env);
+#endif /* HAVE_KQUEUE && HAVE_KEVENT */
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: kevent
+ * Signature: (ILjava/nio/ByteBuffer;IJ)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_kevent (JNIEnv *env,
+ jobject this __attribute__((unused)),
+ jint kq, jobject nstate, jint nevents,
+ jint maxevents, jlong timeout)
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+ struct timespec tv;
+ struct timespec *t = NULL;
+ struct kevent *kev = (struct kevent *) (*env)->GetDirectBufferAddress (env, nstate);
+ int ret;
+
+#ifdef TRACE_KQUEUE
+ int i;
+
+ printf ("[%d] kevent nevents:%d maxevents:%d timeout:%lld\n", kq, nevents, maxevents, timeout);
+ printf ("[%d] addding/deleting %d events\n", kq, nevents);
+ for (i = 0; i < nevents; i++)
+ {
+ printf ("[%d] kevent input [%d]: ident:%u filter:%x flags:%o fflags:%o data:%p udata:%p\n",
+ kq, i, (unsigned) kev[i].ident, kev[i].filter, kev[i].flags, kev[i].fflags,
+ (void *) kev[i].data, kev[i].udata);
+ }
+#endif
+
+/* TRACE("events: %p; nevents: %d; timeout: %lld", (void *) kev, nevents, timeout); */
+
+ if (timeout != -1)
+ {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_nsec = (timeout % 1000) * 1000;
+ t = &tv;
+ }
+
+ ret = kevent (kq, (const struct kevent *) kev, nevents, kev, maxevents, t);
+
+ if (ret == -1)
+ {
+ if (errno == EINTR)
+ ret = 0;
+ else
+ JCL_ThrowException (env, "java/io/IOException", strerror (errno));
+ }
+
+#ifdef TRACE_KQUEUE
+ for (i = 0; i < ret; i++)
+ {
+ printf ("[%d] kevent output [%d]: ident:%u filter:%x flags:%o fflags:%o data:%p udata:%p\n",
+ kq, i, (unsigned) kev[i].ident, kev[i].filter, kev[i].flags, kev[i].fflags,
+ (void *) kev[i].data, kev[i].udata);
+ }
+#endif
+
+ return ret;
+#else
+ (void) kq;
+ (void) nstate;
+ (void) nevents;
+ (void) maxevents;
+ (void) timeout;
+ throw_not_supported (env);
+ return -1;
+#endif /* HAVE_KQUEUE && HAVE_KEVENT */
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: fetch_key
+ * Signature: (Ljava/nio/ByteBuffer;)I;
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_fetch_1key (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jobject nstate)
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+ struct kevent *kev = (struct kevent *) (*env)->GetDirectBufferAddress (env, nstate);
+/* TRACE("return key %p\n", kev->udata); */
+ return (jint) kev->udata;
+#else
+ (void) nstate;
+ throw_not_supported (env);
+ return -1;
+#endif /* HAVE_KQUEUE && HAVE_KEVENT */
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: ready_ops
+ * Signature: (Ljava/nio/ByteBuffer;I)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_ready_1ops (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jobject nstate, jint interest)
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+ struct kevent *kev = (struct kevent *) (*env)->GetDirectBufferAddress (env, nstate);
+ jint ready = 0;
+
+ if ((kev->flags & EV_ERROR) == EV_ERROR)
+ {
+ printf ("!!! error selecting fd %d: %s", (int) (kev->ident), strerror ((int) (kev->data)));
+ return 0;
+ }
+
+ /* We poll for READ for OP_READ and OP_ACCEPT. */
+ if (kev->filter == EVFILT_READ)
+ {
+ ready = (interest & KEY_OP_READ) | (interest & KEY_OP_ACCEPT);
+/* TRACE("filter EVFILT_READ. Ready ops set to %x", ready); */
+ }
+
+ /* Poll for WRITE for OP_WRITE and OP_CONNECT; I guess we *should*
+ get a WRITE event if we are connected, but I don't know if we do
+ for real. FIXME */
+ if (kev->filter == EVFILT_WRITE)
+ {
+ ready = (interest & KEY_OP_WRITE) | (interest & KEY_OP_CONNECT);
+/* TRACE("filter EVFILT_WRITE. Ready ops set to %x", ready); */
+ }
+
+ return ready;
+#else
+ (void) nstate;
+ (void) interest;
+ throw_not_supported (env);
+ return -1;
+#endif /* HAVE_KQUEUE && HAVE_KEVENT */
+}
+
+
+/*
+ * Class: gnu_java_nio_KqueueSelectorImpl
+ * Method: check_eof
+ * Signature: (Ljava/nio/ByteBuffer;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_KqueueSelectorImpl_check_1eof (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jobject nstate)
+{
+#if defined(HAVE_KQUEUE) && defined(HAVE_KEVENT)
+ struct kevent *kev = (struct kevent *) (*env)->GetDirectBufferAddress (env, nstate);
+ if ((kev->flags & EV_EOF) == EV_EOF)
+ return JNI_TRUE;
+ return JNI_FALSE;
+#else
+ (void) nstate;
+ throw_not_supported (env);
+ return JNI_FALSE;
+#endif
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c
new file mode 100644
index 000000000..7899f0b94
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c
@@ -0,0 +1,2035 @@
+/* gnu_java_nio_VMChannel.c -
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 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 <config.h>
+#endif
+
+#include <config-int.h>
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <netinet/in.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "cpio.h"
+#include "gnu_java_nio_VMChannel.h"
+#include "javanio.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#if defined(HAVE_SYS_IOCTL_H)
+#define BSD_COMP /* Get FIONREAD on Solaris2 */
+#include <sys/ioctl.h>
+#endif
+#if defined(HAVE_SYS_FILIO_H) /* Get FIONREAD on Solaris 2.5 */
+#include <sys/filio.h>
+#endif
+
+#define CONNECT_EXCEPTION "java/net/ConnectException"
+#define IO_EXCEPTION "java/io/IOException"
+#define SOCKET_EXCEPTION "java/net/SocketException"
+#define INTERRUPTED_IO_EXCEPTION "java/io/InterruptedIOException"
+#define NON_READABLE_CHANNEL_EXCEPTION "java/nio/channels/NonReadableChannelException"
+#define NON_WRITABLE_CHANNEL_EXCEPTION "java/nio/channels/NonWritableChannelException"
+#define SOCKET_TIMEOUT_EXCEPTION "java/net/SocketTimeoutException"
+
+/* Align a value up or down to a multiple of the pagesize. */
+#define ALIGN_DOWN(p,s) ((p) - ((p) % (s)))
+#define ALIGN_UP(p,s) ((p) + ((s) - ((p) % (s))))
+
+/*
+ * Limit to maximum of 16 buffers
+ */
+#define JCL_IOV_MAX 16
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+enum JCL_buffer_type { DIRECT, HEAP, ARRAY, UNKNOWN };
+
+struct JCL_buffer
+{
+ enum JCL_buffer_type type;
+ jbyte *ptr;
+ jint offset;
+ jint position;
+ jint limit;
+ jint count;
+};
+
+jmethodID get_method_id(JNIEnv *, jclass, const char *, const char *);
+void JCL_print_buffer(JNIEnv *, struct JCL_buffer *);
+int JCL_init_buffer(JNIEnv *, struct JCL_buffer *, jobject);
+void JCL_release_buffer(JNIEnv *, struct JCL_buffer *, jobject, jint);
+void JCL_cleanup_buffers(JNIEnv *, struct JCL_buffer *, jint, jobjectArray, jint, jlong);
+int JCL_thread_interrupted(JNIEnv *);
+
+static jfieldID address_fid;
+static jmethodID get_position_mid;
+static jmethodID set_position_mid;
+static jmethodID get_limit_mid;
+static jmethodID set_limit_mid;
+static jmethodID has_array_mid;
+static jmethodID array_mid;
+static jmethodID array_offset_mid;
+static jmethodID thread_interrupted_mid;
+static jclass vm_channel_class;
+
+jmethodID
+get_method_id(JNIEnv *env, jclass clazz, const char *name,
+ const char *sig)
+{
+ jmethodID mid = (*env)->GetMethodID(env, clazz, name, sig);
+/* NIODBG("name: %s; sig: %s", name, sig); */
+ if (mid == NULL)
+ {
+ JCL_ThrowException(env, "java/lang/InternalError", name);
+ return NULL;
+ }
+
+ return mid;
+}
+
+inline void
+JCL_print_buffer(JNIEnv *env __attribute__((__unused__)), struct JCL_buffer *buf)
+{
+ fprintf (stderr, "Buffer - type: %d, ptr: %p\n", buf->type, buf->ptr);
+}
+
+
+int
+JCL_init_buffer(JNIEnv *env, struct JCL_buffer *buf, jobject bbuf)
+{
+ void *addr = (*env)->GetDirectBufferAddress (env, bbuf);
+
+/* NIODBG("buf: %p; bbuf: %p; addr: %p", (void *) buf, bbuf, addr); */
+
+ buf->position = (*env)->CallIntMethod(env, bbuf, get_position_mid);
+ buf->limit = (*env)->CallIntMethod(env, bbuf, get_limit_mid);
+ buf->offset = 0;
+ buf->count = 0;
+ buf->type = UNKNOWN;
+
+ if (addr != NULL)
+ {
+ buf->ptr = (jbyte *) addr;
+ buf->type = DIRECT;
+ }
+ else
+ {
+ jboolean has_array;
+ has_array = (*env)->CallBooleanMethod(env, bbuf, has_array_mid);
+
+ if (has_array == JNI_TRUE)
+ {
+ jbyteArray arr;
+ buf->offset = (*env)->CallIntMethod(env, bbuf, array_offset_mid);
+ arr = (*env)->CallObjectMethod(env, bbuf, array_mid);
+ buf->ptr = (*env)->GetByteArrayElements(env, arr, 0);
+ buf->type = ARRAY;
+ (*env)->DeleteLocalRef(env, arr);
+ }
+ else
+ {
+ jobject address = (*env)->GetObjectField (env, bbuf, address_fid);
+ if (address == NULL)
+ return -1; /* XXX handle non-array, non-native buffers? */
+ buf->ptr = (jbyte *) JCL_GetRawData(env, address);
+ buf->type = HEAP;
+ (*env)->DeleteLocalRef(env, address);
+ }
+ }
+
+ return 0;
+}
+
+void
+JCL_release_buffer(JNIEnv *env, struct JCL_buffer *buf, jobject bbuf,
+ jint action)
+{
+ jbyteArray arr;
+
+/* NIODBG("buf: %p; bbuf: %p; action: %x", (void *) buf, bbuf, action); */
+
+ /* Set the position to the appropriate value */
+ if (buf->count > 0)
+ {
+ jobject bbufTemp;
+ bbufTemp = (*env)->CallObjectMethod(env, bbuf, set_position_mid,
+ buf->position + buf->count);
+ (*env)->DeleteLocalRef(env, bbufTemp);
+ }
+
+ switch (buf->type)
+ {
+ case DIRECT:
+ case HEAP:
+ break;
+ case ARRAY:
+ arr = (*env)->CallObjectMethod(env, bbuf, array_mid);
+ (*env)->ReleaseByteArrayElements(env, arr, buf->ptr, action);
+ (*env)->DeleteLocalRef(env, arr);
+ break;
+ case UNKNOWN:
+ /* TODO: Handle buffers that are not direct or array backed */
+ break;
+ }
+}
+
+void
+JCL_cleanup_buffers(JNIEnv *env,
+ struct JCL_buffer *bi_list,
+ jint vec_len,
+ jobjectArray bbufs,
+ jint offset,
+ jlong num_bytes)
+{
+ jint i;
+
+/* NIODBG("bi_list: %p; vec_len: %d; bbufs: %p; offset: %d; num_bytes: %lld", */
+/* (void *) bi_list, vec_len, bbufs, offset, num_bytes); */
+
+ /* Update all of the bbufs with the approriate information */
+ for (i = 0; i < vec_len; i++)
+ {
+ struct JCL_buffer* buf;
+ jobject bbuf;
+
+ buf = &bi_list[i];
+ bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i);
+
+ if (num_bytes > (buf->limit - buf->position))
+ buf->count = (buf->limit - buf->position);
+ else
+ buf->count = num_bytes;
+
+ num_bytes -= buf->count;
+
+ JCL_release_buffer(env, buf, bbuf, JNI_ABORT);
+ (*env)->DeleteLocalRef(env, bbuf);
+ }
+}
+
+
+int
+JCL_thread_interrupted(JNIEnv *env)
+{
+ return (int) (*env)->CallStaticBooleanMethod(env, vm_channel_class,
+ thread_interrupted_mid);
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: stdin_fd
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_stdin_1fd (JNIEnv *env __attribute__((unused)),
+ jclass c __attribute__((unused)))
+{
+/* NIODBG("%d", fileno (stdin)); */
+ return fileno (stdin);
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: stdout_fd
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_stdout_1fd (JNIEnv *env __attribute__((unused)),
+ jclass c __attribute__((unused)))
+{
+/* NIODBG("%d", fileno (stdout)); */
+ return fileno (stdout);
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: stderr_fd
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_stderr_1fd (JNIEnv *env __attribute__((unused)),
+ jclass c __attribute__((unused)))
+{
+/* NIODBG("%d", fileno (stderr)); */
+ return fileno (stderr);
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_initIDs (JNIEnv *env,
+ jclass clazz)
+{
+ jclass bufferClass = JCL_FindClass(env, "java/nio/Buffer");
+ jclass byteBufferClass = JCL_FindClass(env, "java/nio/ByteBuffer");
+
+/* NIODBG("%s", "..."); */
+
+ address_fid = (*env)->GetFieldID(env, bufferClass, "address",
+ "Lgnu/classpath/Pointer;");
+ if (address_fid == NULL)
+ {
+ JCL_ThrowException(env, "java/lang/InternalError",
+ "Unable to find internal field");
+ return;
+ }
+
+ get_position_mid = get_method_id(env, bufferClass, "position", "()I");
+ set_position_mid = get_method_id(env, bufferClass, "position",
+ "(I)Ljava/nio/Buffer;");
+ get_limit_mid = get_method_id(env, bufferClass, "limit", "()I");
+ set_limit_mid = get_method_id(env, bufferClass, "limit",
+ "(I)Ljava/nio/Buffer;");
+ has_array_mid = get_method_id(env, byteBufferClass, "hasArray", "()Z");
+ array_mid = get_method_id(env, byteBufferClass, "array", "()[B");
+ array_offset_mid = get_method_id(env, byteBufferClass, "arrayOffset", "()I");
+
+ vm_channel_class = clazz;
+ thread_interrupted_mid = (*env)->GetStaticMethodID(env, clazz,
+ "isThreadInterrupted",
+ "()Z");
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_setBlocking (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jboolean blocking)
+{
+ int opts;
+
+/* NIODBG("fd: %d; blocking: %d", fd, blocking); */
+
+ opts = fcntl(fd, F_GETFL);
+ if (opts < 0)
+ {
+ JCL_ThrowException(env, IO_EXCEPTION,
+ "Failed to get flags for file desriptor");
+ return;
+ }
+
+ if (blocking == JNI_TRUE)
+ opts &= ~(O_NONBLOCK);
+ else
+ opts |= O_NONBLOCK;
+
+ opts = fcntl(fd, F_SETFL, opts);
+
+ if (opts < 0)
+ {
+ JCL_ThrowException(env, IO_EXCEPTION,
+ "Failed to set flags for file desriptor");
+ return;
+ }
+}
+
+/* Return true if fd is in non-blocking mode. */
+static jboolean
+is_non_blocking_fd(jint fd)
+{
+ int opts;
+ opts = fcntl(fd, F_GETFL);
+ if (opts == -1)
+ {
+ /* Assume blocking on error. */
+ return 0;
+ }
+ return (opts & O_NONBLOCK) != 0;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_read__ILjava_nio_ByteBuffer_2 (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobject bbuf)
+{
+#ifdef HAVE_READ
+ jint len;
+ ssize_t result;
+ struct JCL_buffer buf;
+ int tmp_errno;
+
+/* NIODBG("fd: %d; bbuf: %p", fd, bbuf); */
+
+ if (JCL_init_buffer(env, &buf, bbuf) < 0)
+ {
+ /* TODO: Rethrown exception */
+ JCL_ThrowException (env, IO_EXCEPTION, "Buffer initialisation failed");
+ return -1;
+ }
+
+ len = buf.limit - buf.position;
+
+ if (len == 0)
+ {
+ JCL_release_buffer (env, &buf, bbuf, JNI_ABORT);
+ return 0;
+ }
+
+ do
+ {
+ result = cpnio_read (fd, &(buf.ptr[buf.position + buf.offset]), len);
+ tmp_errno = errno;
+ }
+ while (result == -1 && errno == EINTR && ! JCL_thread_interrupted(env));
+ errno = tmp_errno;
+
+ if (result == 0)
+ {
+ result = -1;
+ buf.count = 0;
+ }
+ else if (result == -1)
+ {
+ buf.count = 0;
+ if (errno == EAGAIN)
+ {
+ if (is_non_blocking_fd(fd))
+ {
+ /* Non-blocking */
+ result = 0;
+ }
+ else
+ {
+ /* Read timeout on a socket with SO_RCVTIMEO != 0. */
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException(env, SOCKET_TIMEOUT_EXCEPTION, "read timed out");
+ return -1;
+ }
+ }
+ else if (errno == EBADF) /* Bad fd */
+ {
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException (env, NON_READABLE_CHANNEL_EXCEPTION,
+ strerror(errno));
+ return -1;
+ }
+ else if (EINTR == errno) /* read interrupted */
+ {
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException(env, INTERRUPTED_IO_EXCEPTION, strerror (errno));
+ return -1;
+ }
+ else
+ {
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException (env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ }
+ else
+ buf.count = result;
+
+ JCL_release_buffer(env, &buf, bbuf, 0);
+
+ return result;
+#else
+ (void) fd;
+ (void) bbuf;
+ JCL_ThrowException (env, IO_EXCEPTION, "read not supported");
+ return -1;
+#endif /* HAVE_READ */
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_write__ILjava_nio_ByteBuffer_2 (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobject bbuf)
+{
+#ifdef HAVE_WRITE
+ jint len;
+ ssize_t result;
+ struct JCL_buffer buf;
+ int tmp_errno;
+
+/* NIODBG("fd: %d; bbuf: %p", fd, bbuf); */
+
+ if (JCL_init_buffer(env, &buf, bbuf) < 0)
+ {
+ /* TODO: Rethrown exception */
+ JCL_ThrowException (env, IO_EXCEPTION, "Buffer initialisation failed");
+ return -1;
+ }
+
+ len = buf.limit - buf.position;
+
+ if (len == 0)
+ {
+ JCL_release_buffer (env, &buf, bbuf, JNI_ABORT);
+ return 0;
+ }
+
+ do
+ {
+ result = cpnio_write (fd, &(buf.ptr[buf.position + buf.offset]), len);
+ tmp_errno = errno;
+ }
+ while (result == -1 && errno == EINTR && ! JCL_thread_interrupted(env));
+ errno = tmp_errno;
+
+ buf.count = result;
+
+ if (result == -1)
+ {
+ if (errno == EAGAIN) /* Non-blocking */
+ {
+ result = 0;
+ }
+ else
+ {
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException(env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ }
+
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+
+ return result;
+#else
+ (void) fd;
+ (void) bbuf;
+ JCL_ThrowException (env, IO_EXCEPTION, "write not supported");
+ return -1;
+#endif /* HAVE_WRITE */
+}
+
+
+/*
+ * Implementation of a scattering read. Will use the appropriate
+ * vector based read call (currently readv on Linux).
+ *
+ * This has a limit to the number of buffers that will be read. It
+ * will not make muliple readv calls. This is to ensure that operations
+ * are atomic. Currently it is limited to 16 buffers. This is for
+ * compatibiliy with Sun.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_VMChannel_readScattering (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobjectArray bbufs,
+ jint offset,
+ jint length)
+{
+ jint i;
+/* jboolean is_error = JNI_FALSE; */
+/* char *error_msg; */
+ struct iovec buffers[JCL_IOV_MAX];
+ struct JCL_buffer bi_list[JCL_IOV_MAX];
+ ssize_t result;
+ jint vec_len = length < JCL_IOV_MAX ? length : JCL_IOV_MAX;
+ jlong bytes_read = 0;
+ int tmp_errno;
+
+/* NIODBG("fd: %d; bbufs: %p; offset: %d; length: %d", */
+/* fd, bbufs, offset, length); */
+
+ /* Build the vector of buffers to read into */
+ for (i = 0; i < vec_len; i++)
+ {
+ struct JCL_buffer* buf;
+ jobject bbuf;
+
+ buf = &bi_list[i];
+ bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i);
+
+ JCL_init_buffer(env, buf, bbuf);
+
+/* JCL_print_buffer (env, buf); */
+
+ buffers[i].iov_base = &(buf->ptr[buf->position + buf->offset]);
+ buffers[i].iov_len = buf->limit - buf->position;
+ (*env)->DeleteLocalRef(env, bbuf);
+ }
+
+ /* Work the scattering magic */
+ do
+ {
+ result = cpnio_readv (fd, buffers, vec_len);
+ tmp_errno = errno;
+ }
+ while (result == -1 && errno == EINTR && ! JCL_thread_interrupted(env));
+ errno = tmp_errno;
+ bytes_read = (jlong) result;
+
+ /* Handle the response */
+ if (result < 0)
+ {
+ if (errno == EAGAIN)
+ {
+ if (is_non_blocking_fd(fd))
+ {
+ /* Non-blocking */
+ result = 0;
+ }
+ else
+ {
+ /* Read timeout on a socket with SO_RCVTIMEO != 0. */
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
+ JCL_ThrowException(env, SOCKET_TIMEOUT_EXCEPTION, "read timed out");
+ return -1;
+ }
+ }
+ else if (errno == EBADF) /* Bad fd */
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
+ JCL_ThrowException (env, NON_READABLE_CHANNEL_EXCEPTION,
+ strerror(errno));
+ return -1;
+ }
+ else
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
+ JCL_ThrowException (env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ bytes_read = 0;
+ }
+ else if (result == 0) /* EOF */
+ {
+ result = -1;
+ }
+
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
+
+ return (jlong) result;
+}
+
+
+/*
+ * Implementation of a gathering write. Will use the appropriate
+ * vector based read call (currently readv on Linux).
+ *
+ * This has a limit to the number of buffers that will be read. It
+ * will not make muliple readv calls. This is to ensure that operations
+ * are atomic. Currently it is limited to 16 buffers. This is for
+ * compatibiliy with Sun.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_VMChannel_writeGathering (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobjectArray bbufs,
+ jint offset,
+ jint length)
+{
+ int i;
+/* jboolean is_error = JNI_FALSE; */
+/* char *error_msg; */
+ struct iovec buffers[JCL_IOV_MAX];
+ struct JCL_buffer bi_list[JCL_IOV_MAX];
+ ssize_t result;
+ jint vec_len = length < JCL_IOV_MAX ? length : JCL_IOV_MAX;
+ jlong bytes_written;
+ int tmp_errno;
+
+/* NIODBG("fd: %d; bbufs: %p; offset: %d; length: %d", */
+/* fd, bbufs, offset, length); */
+
+ /* Build the vector of buffers to read into */
+ for (i = 0; i < vec_len; i++)
+ {
+ struct JCL_buffer* buf;
+ jobject bbuf;
+
+ buf = &bi_list[i];
+ bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i);
+
+ JCL_init_buffer(env, buf, bbuf);
+
+/* JCL_print_buffer(env, buf); */
+
+ buffers[i].iov_base = &(buf->ptr[buf->position + buf->offset]);
+ buffers[i].iov_len = buf->limit - buf->position;
+ (*env)->DeleteLocalRef(env, bbuf);
+ }
+
+ /* Work the gathering magic */
+ do
+ {
+ result = cpnio_writev (fd, buffers, vec_len);
+ tmp_errno = errno;
+ }
+ while (result == -1 && tmp_errno == EINTR && ! JCL_thread_interrupted(env));
+ errno = tmp_errno;
+
+ bytes_written = (jlong) result;
+
+ if (result < 0)
+ {
+ bytes_written = 0;
+ if (errno == EAGAIN) /* Non blocking */
+ result = 0;
+ else if (errno == EBADF) /* Bad fd */
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset,
+ bytes_written);
+ JCL_ThrowException (env, NON_WRITABLE_CHANNEL_EXCEPTION,
+ strerror(errno));
+ return -1;
+ }
+ else
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset,
+ bytes_written);
+ JCL_ThrowException (env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ }
+ else if (result == 0) /* EOF?? Does this happen on a write */
+ result = -1;
+
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_written);
+ return (jlong) result;
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: receive
+ * Signature: (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_receive (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jobject dst, jobject addrPort)
+{
+#ifdef HAVE_RECVFROM
+ char *addrPortPtr = (*env)->GetDirectBufferAddress (env, addrPort);
+ struct JCL_buffer buf;
+#ifdef HAVE_INET6
+ struct sockaddr_in6 sock_storage;
+ struct sockaddr_in6 *sock6;
+ socklen_t slen = sizeof (struct sockaddr_in6);
+#else
+ struct sockaddr_in sock_storage;
+ socklen_t slen = sizeof (struct sockaddr_in);
+#endif /* HAVE_INET6 */
+ struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
+ struct sockaddr_in *sock4;
+ int ret;
+ jint result = -1;
+
+ if (JCL_init_buffer (env, &buf, dst) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, "loading buffer failed");
+
+#ifndef HAVE_MSG_WAITALL
+#define MSG_WAITALL 0
+#endif
+
+ ret = cpnio_recvfrom (fd, &(buf.ptr[buf.position + buf.offset]),
+ buf.limit - buf.position, MSG_WAITALL,
+ sockaddr, &slen);
+
+ if (-1 == ret)
+ {
+ JCL_release_buffer (env, &buf, dst, JNI_ABORT);
+ if (EINTR == errno)
+ JCL_ThrowException (env, "java/io/InterruptedIOException", strerror (errno));
+ else if (EAGAIN == errno)
+ {
+ /* If the socket is in blocking mode, our timeout expired. */
+ int val = fcntl (fd, F_GETFL, 0);
+ if (val == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ else if ((val & O_NONBLOCK) == 0)
+ JCL_ThrowException (env, "java/net/SocketTimeoutException",
+ "read timed out");
+ }
+ else
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return 0;
+ }
+
+ if (sockaddr->sa_family == AF_INET)
+ {
+ sock4 = (struct sockaddr_in *) sockaddr;
+ memcpy (addrPortPtr, &(sock4->sin_addr.s_addr), 4);
+ ;memcpy (addrPortPtr + 4, &(sock4->sin_port), 2);
+ result = 4;
+ }
+#ifdef HAVE_INET6
+ else if (sockaddr->sa_family == AF_INET6)
+ {
+ sock6 = (struct sockaddr_in6 *) sockaddr;
+ memcpy (addrPortPtr, &(sock6->sin6_addr.s6_addr), 16);
+ memcpy (addrPortPtr + 16, &(sock6->sin6_port), 2);
+ result = 16;
+ }
+#endif /* HAVE_INET6 */
+ else if (ret == 0)
+ {
+ result = 0;
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/net/SocketException",
+ "unsupported address type returned");
+ }
+
+ buf.count += ret;
+ JCL_release_buffer (env, &buf, dst, 0);
+ return result;
+#else
+ (void) fd;
+ (void) dst;
+ (void) addrPort;
+ JCL_ThrowException (env, IO_EXCEPTION, "recvfrom not supported");
+#endif /* HAVE_RECVFROM */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: send
+ * Signature: (Ljava/nio/ByteBuffer;[BI)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_send (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ int fd, jobject src, jbyteArray addr, jint port)
+{
+#ifdef HAVE_SENDTO
+ struct sockaddr_in sockaddr;
+ jbyte *elems;
+ struct JCL_buffer buf;
+ int ret;
+
+/* NIODBG("fd: %d; src: %p; addr: %p; port: %d", */
+/* fd, src, addr, port); */
+
+ if (JCL_init_buffer (env, &buf, src) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "loading buffer failed");
+ return -1;
+ }
+
+/* JCL_print_buffer (env, &buf); */
+
+ elems = (*env)->GetByteArrayElements (env, addr, NULL);
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_addr.s_addr = *((uint32_t *) elems);
+ sockaddr.sin_port = htons (port);
+
+ do
+ {
+ ret = cpnio_sendto (fd, &(buf.ptr[buf.position + buf.offset]),
+ buf.limit - buf.position,
+ 0, (const struct sockaddr *) &sockaddr,
+ sizeof (struct sockaddr_in));
+ }
+ while (-1 == ret && EINTR == errno);
+
+ (*env)->ReleaseByteArrayElements (env, addr, elems, JNI_ABORT);
+
+ if (-1 == ret)
+ {
+ if (errno != EAGAIN)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_release_buffer (env, &buf, src, JNI_ABORT);
+ return 0;
+ }
+
+ buf.count += ret;
+ JCL_release_buffer (env, &buf, src, JNI_ABORT);
+ return ret;
+#else
+ (void) fd;
+ (void) src;
+ (void) addr;
+ (void) port;
+#endif /* HAVE_SENDTO */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: send6
+ * Signature: (Ljava/nio/ByteBuffer;[BI)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_send6 (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ int fd, jobject src, jbyteArray addr, jint port)
+{
+#if defined(HAVE_SENDTO) && defined(HAVE_INET6)
+ struct sockaddr_in6 sockaddr;
+ jbyte *elems;
+ struct JCL_buffer buf;
+ int ret;
+
+/* NIODBG("fd: %d; src: %p; addr: %p; port: %d", */
+/* fd, src, addr, port); */
+
+ if (JCL_init_buffer (env, &buf, src) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "loading buffer failed");
+ return -1;
+ }
+
+/* JCL_print_buffer (env, &buf); */
+
+ elems = (*env)->GetByteArrayElements (env, addr, NULL);
+
+ sockaddr.sin6_family = AF_INET6;
+ memcpy (&sockaddr.sin6_addr.s6_addr, elems, 16);
+ sockaddr.sin6_port = htons (port);
+
+ do
+ {
+ ret = cpnio_sendto (fd, (const void *) (buf.ptr + buf.offset),
+ buf.limit - buf.position,
+ 0, (const struct sockaddr *) &sockaddr,
+ sizeof (struct sockaddr_in6));
+ }
+ while (-1 == ret && EINTR == errno);
+
+ (*env)->ReleaseByteArrayElements (env, addr, elems, JNI_ABORT);
+
+ if (-1 == ret)
+ {
+ if (errno != EAGAIN)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_release_buffer (env, &buf, src, JNI_ABORT);
+ return 0;
+ }
+
+ buf.count += ret;
+ JCL_release_buffer (env, &buf, src, JNI_ABORT);
+ return ret;
+#else
+ (void) fd;
+ (void) src;
+ (void) addr;
+ (void) port;
+ JCL_ThrowException (env, IO_EXCEPTION, "IPv6 sendto not supported");
+ return -1;
+#endif /* HAVE_SENDTO && HAVE_INET6 */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: read
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_read__I (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+#ifdef HAVE_READ
+ char in;
+ int ret;
+ int tmp_errno;
+
+/* NIODBG("fd: %d", fd); */
+
+ do
+ {
+ ret = cpnio_read (fd, &in, 1);
+ tmp_errno = errno;
+ }
+ while (ret == -1 && errno == EINTR && ! JCL_thread_interrupted(env));
+ errno = tmp_errno;
+
+ if (-1 == ret)
+ {
+ if (errno == EAGAIN && !is_non_blocking_fd(fd))
+ {
+ /* Read timeout on a socket with SO_RCVTIMEO != 0. */
+ JCL_ThrowException(env, SOCKET_TIMEOUT_EXCEPTION, "read timed out");
+ }
+ else
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return -1;
+ }
+
+ if (0 == ret)
+ return -1;
+
+ return (in & 0xFF);
+#else
+ (void) fd;
+ JCL_ThrowException (env, IO_EXCEPTION, "read not supported");
+#endif /* HAVE_READ */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: write
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_write__II (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jint data)
+{
+#ifdef HAVE_WRITE
+ char out = (char) data;
+ int ret;
+ int tmp_errno;
+
+/* NIODBG("fd: %d; data: %d", fd, data); */
+
+ do
+ {
+ ret = cpnio_write (fd, &out, 1);
+ tmp_errno = errno;
+ }
+ while (ret == -1 && errno == EINTR && ! JCL_thread_interrupted(env));
+ errno = tmp_errno;
+
+ if (-1 == ret)
+ JCL_ThrowException(env, IO_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) data;
+ JCL_ThrowException (env, IO_EXCEPTION, "write not supported");
+#endif /* HAVE_WRITE */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: socket
+ * Signature: (Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_socket (JNIEnv *env, jclass clazz __attribute__((unused)),
+ jboolean stream)
+{
+#ifdef HAVE_SOCKET
+ int ret;
+
+ do
+ {
+ ret = cpnio_socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
+ }
+ while (-1 == ret && EINTR == errno);
+
+ if (ret == -1)
+ JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
+/* NIODBG("created socket %d", ret); */
+
+ return ret;
+#else
+ (void) stream;
+ JCL_ThrowException (env, IO_EXCEPTION, "socket not supported");
+ return -1;
+#endif /* HAVE_SOCKET */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: connect
+ * Signature: (I[BI)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((unused)),
+ jint fd, jbyteArray addr, jint port, jint timeout)
+{
+#ifdef HAVE_CONNECT
+ struct sockaddr_in sockaddr;
+ struct timeval timeo;
+ int origflags = 0, flags;
+ jbyte *addr_elems;
+ int ret;
+ int tmpErrno;
+
+ if ((*env)->GetArrayLength (env, addr) != 4)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "expecting 4-byte address");
+ return JNI_FALSE;
+ }
+
+ if (timeout > 0)
+ {
+ timeo.tv_sec = timeout / 1000;
+ timeo.tv_usec = (timeout % 1000) * 1000;
+ origflags = fcntl (fd, F_GETFL, 0);
+ if (origflags == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ /* Set nonblocking mode, if not already set. */
+ if (!(origflags & O_NONBLOCK))
+ {
+ flags = origflags | O_NONBLOCK;
+ if (fcntl (fd, F_SETFL, flags) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+ }
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+
+ memset (&sockaddr, 0, sizeof (struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons (port);
+ sockaddr.sin_addr.s_addr = *((uint32_t *) addr_elems);
+
+
+ do
+ {
+ ret = cpnio_connect (fd, (struct sockaddr *) &sockaddr,
+ sizeof (struct sockaddr_in));
+ tmpErrno = errno;
+ }
+ while (ret == -1 && errno == EINTR && ! JCL_thread_interrupted(env));
+ errno = tmpErrno;
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ /* If a timeout was specified, select on the file descriptor with
+ the timeout. */
+ if (timeout > 0 && ret == -1)
+ {
+ /* Reset the non-blocking flag, if needed. */
+ if (!(origflags & O_NONBLOCK))
+ {
+ if (fcntl (fd, F_SETFL, origflags) == -1)
+ {
+ /* oops */
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+ if (EINPROGRESS == errno)
+ {
+ fd_set wrfds;
+ FD_ZERO(&wrfds);
+ FD_SET(fd, &wrfds);
+ ret = cpnio_select (fd + 1, NULL, &wrfds, NULL, &timeo);
+ if (ret == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ if (ret == 0) /* connect timed out */
+ {
+ JCL_ThrowException (env, SOCKET_TIMEOUT_EXCEPTION,
+ "connect timed out");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE; /* Connected! */
+ }
+ else if (ECONNREFUSED == errno)
+ {
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
+ strerror (errno));
+ return JNI_FALSE;
+ }
+ else
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+
+ if (ret == -1)
+ {
+ if (EINPROGRESS == errno)
+ return JNI_FALSE;
+ else if (ECONNREFUSED == errno)
+ {
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
+ strerror (errno));
+ return JNI_FALSE;
+ }
+ else
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+
+ return JNI_TRUE;
+#else
+ (void) fd;
+ (void) addr;
+ (void) port;
+ (void) timeout;
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "connect not supported");
+ return JNI_FALSE;
+#endif /* HAVE_CONNECT */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: connect6
+ * Signature: (I[BI)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((unused)),
+ jint fd, jbyteArray addr, jint port, int timeout)
+{
+#if defined(HAVE_CONNECT) && defined(HAVE_INET6)
+ struct sockaddr_in6 sockaddr;
+ struct timeval timeo;
+ int flags, origflags = 0;
+ jbyte *addr_elems;
+ int ret;
+
+ if (timeout > 0)
+ {
+ timeo.tv_sec = timeout / 1000;
+ timeo.tv_usec = (timeout % 1000) * 1000;
+ origflags = fcntl (fd, F_GETFL, 0);
+ if (origflags == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ /* Set nonblocking mode, if not already set. */
+ if (!(origflags & O_NONBLOCK))
+ {
+ flags = origflags | O_NONBLOCK;
+ if (fcntl (fd, F_SETFL, flags) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+ }
+
+ addr_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, addr_elems, 16);
+
+ ret = cpnio_connect (fd, (struct sockaddr *) &sockaddr,
+ sizeof (struct sockaddr_in6));
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ /* If a timeout was specified, select on the file descriptor with
+ the timeout. */
+ if (timeout > 0 && ret == -1)
+ {
+ /* Reset the non-blocking flag, if needed. */
+ if (!(origflags & O_NONBLOCK))
+ {
+ if (fcntl (fd, F_SETFL, origflags) == -1)
+ {
+ /* oops */
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+ if (EINPROGRESS == errno)
+ {
+ fd_set wrfds;
+ FD_ZERO(&wrfds);
+ FD_SET(fd, &wrfds);
+ ret = cpnio_select (fd + 1, NULL, &wrfds, NULL, &timeo);
+ if (ret == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ if (ret == 0) /* connect timed out */
+ {
+ JCL_ThrowException (env, SOCKET_TIMEOUT_EXCEPTION,
+ "connect timed out");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE; /* Connected! */
+ }
+ else if (ECONNREFUSED == errno)
+ {
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
+ strerror (errno));
+ return JNI_FALSE;
+ }
+ else
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+
+ if (ret == -1)
+ {
+ if (EAGAIN == errno)
+ return JNI_FALSE;
+ else if (ECONNREFUSED == errno)
+ {
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
+ strerror (errno));
+ return JNI_FALSE;
+ }
+ else
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ }
+
+ return JNI_TRUE;
+#else
+ (void) fd;
+ (void) addr;
+ (void) port;
+ (void) timeout;
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "IPv6 connect not supported");
+ return JNI_FALSE;
+#endif /* HAVE_CONNECT && HAVE_INET6 */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: getsockname
+ * Signature: (ILjava/nio/ByteBuffer;)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_getsockname (JNIEnv *env, jclass clazz __attribute__((unused)),
+ jint fd, jobject name)
+{
+#ifdef HAVE_GETSOCKNAME
+#ifdef HAVE_INET6
+ struct sockaddr_in6 *addr6;
+ struct sockaddr_in6 sock_storage;
+ socklen_t socklen = sizeof (struct sockaddr_in6);
+#else
+ struct sockaddr_in sock_storage;
+ socklen_t socklen = sizeof (struct sockaddr_in);
+#endif /* HAVE_INET6 */
+
+ struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
+ struct sockaddr_in *addr4;
+ int ret;
+ char *nameptr = (*env)->GetDirectBufferAddress (env, name);
+
+ ret = getsockname (fd, sockaddr, &socklen);
+ if (ret == -1)
+ {
+ JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
+ return 0;
+ }
+
+ if (sockaddr->sa_family == AF_INET)
+ {
+ addr4 = (struct sockaddr_in *) sockaddr;
+ memcpy (nameptr, &(addr4->sin_addr.s_addr), 4);
+ memcpy (nameptr + 4, &(addr4->sin_port), 2);
+ return 4;
+ }
+
+#ifdef HAVE_INET6
+ /* IPv6 */
+ if (sockaddr->sa_family == AF_INET6)
+ {
+ addr6 = (struct sockaddr_in6 *) sockaddr;
+ memcpy (nameptr, &(addr6->sin6_addr.s6_addr), 16);
+ memcpy (nameptr + 16, &(addr6->sin6_port), 2);
+ return 16;
+ }
+#endif /* HAVE_INET6 */
+ JCL_ThrowException (env, IO_EXCEPTION, "unsupported address format");
+ return -1;
+#else
+ (void) fd;
+ (void) name;
+ JCL_ThrowException (env, IO_EXCEPTION, "getsockname not supported");
+ return -1;
+#endif /* HAVE_GETSOCKNAME */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: getpeername
+ * Signature: (ILjava/nio/ByteBuffer;)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_getpeername (JNIEnv *env, jclass clazz __attribute__((unused)),
+ jint fd, jobject name)
+{
+#ifdef HAVE_GETPEERNAME
+#ifdef HAVE_INET6
+ struct sockaddr_in6 *addr6;
+ struct sockaddr_in6 sock_storage;
+ socklen_t socklen = sizeof (struct sockaddr_in6);
+#else
+ struct sockaddr_in sock_storage;
+ socklen_t socklen = sizeof (struct sockaddr_in);
+#endif /* HAVE_INET6 */
+
+ struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
+ struct sockaddr_in *addr4;
+ int ret;
+ char *nameptr = (*env)->GetDirectBufferAddress (env, name);
+
+ ret = getpeername (fd, sockaddr, &socklen);
+ if (ret == -1)
+ {
+ if (ENOTCONN != errno)
+ JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
+ return 0;
+ }
+
+ if (sockaddr->sa_family == AF_INET)
+ {
+ addr4 = (struct sockaddr_in *) sockaddr;
+ memcpy (nameptr, &(addr4->sin_addr.s_addr), 4);
+ memcpy (nameptr + 4, &(addr4->sin_port), 2);
+ return 4;
+ }
+#ifdef HAVE_INET6
+ else if (sockaddr->sa_family == AF_INET6)
+ {
+ addr6 = (struct sockaddr_in6 *) sockaddr;
+ memcpy (nameptr, &(addr6->sin6_addr.s6_addr), 16);
+ memcpy (nameptr + 16, &(addr6->sin6_port), 2);
+ return 16;
+ }
+#endif /* HAVE_INET6 */
+
+ JCL_ThrowException (env, "java/net/SocketException",
+ "unsupported address type");
+ return -1;
+#else
+ (void) fd;
+ (void) name;
+ JCL_ThrowException (env, IO_EXCEPTION, "getpeername not supported");
+ return -1;
+#endif /* HAVE_GETPEERNAME */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: accept
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_accept (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+#ifdef HAVE_ACCEPT
+ int ret;
+ int tmp_errno = 0;
+
+#ifdef HAVE_INET6
+ struct sockaddr_in6 addr;
+ socklen_t alen = sizeof (struct sockaddr_in6);
+#else
+ struct sockaddr_in addr;
+ socklen_t alen = sizeof (struct sockaddr_in);
+#endif /* HAVE_INET6 */
+
+ do
+ {
+ ret = cpnio_accept (fd, (struct sockaddr *) &addr, &alen);
+ tmp_errno = errno;
+
+ if (ret == -1)
+ switch (tmp_errno)
+ {
+ case EINTR:
+ /* Check if interrupted by Thread.interrupt(). If not then some
+ * other unrelated signal interrupted the system function and
+ * we should start over again.
+ */
+ if (JCL_thread_interrupted(env))
+ {
+ JCL_ThrowException (env, "java/net/SocketException", strerror (tmp_errno));
+ return -1;
+ }
+ break;
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ case EAGAIN:
+ if (!is_non_blocking_fd(fd))
+ {
+ JCL_ThrowException(env, SOCKET_TIMEOUT_EXCEPTION, "Accept timed out");
+ }
+ /* Socket in non-blocking mode and no pending connection. */
+ return -1;
+ default:
+ JCL_ThrowException (env, "java/net/SocketException", strerror (tmp_errno));
+ return -1;
+ }
+ else
+ break;
+ }
+ while (1);
+
+ cpio_closeOnExec(ret);
+
+ return ret;
+#else
+ (void) fd;
+ JCL_ThrowException (env, IO_EXCEPTION, "accept not supported");
+ return -1;
+#endif /* HAVE_ACCEPT */
+}
+
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: disconnect
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_disconnect (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+ struct sockaddr sockaddr;
+
+ sockaddr.sa_family = AF_UNSPEC;
+ if (connect (fd, &sockaddr, sizeof (struct sockaddr)) == -1)
+ {
+ /* The expected error for a successful disconnect is EAFNOSUPPORT. */
+ if (errno != EAFNOSUPPORT)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: close
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_close (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+ if (close (fd) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: available
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_available (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+#if defined (FIONREAD)
+
+ jint avail = 0;
+
+#if defined(ENOTTY) && defined(HAVE_FSTAT)
+ struct stat statBuffer;
+ off_t n;
+#endif
+
+/* NIODBG("fd: %d", fd); */
+ if (ioctl (fd, FIONREAD, &avail) == -1)
+ {
+#if defined(ENOTTY) && defined(HAVE_FSTAT)
+ if (errno == ENOTTY)
+ {
+ if ((fstat (fd, &statBuffer) == 0) && S_ISREG (statBuffer.st_mode))
+ {
+ n = lseek (fd, 0, SEEK_CUR);
+ if (n != -1)
+ {
+ avail = statBuffer.st_size - n;
+ return avail;
+ }
+ }
+ }
+#endif
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+/* NIODBG("avail: %d", avail); */
+
+ return avail;
+
+#elif defined(HAVE_FSTAT)
+
+ jint avail = 0;
+
+ struct stat statBuffer;
+ off_t n;
+
+ if ((fstat (fd, &statBuffer) == 0) && S_ISREG (statBuffer.st_mode))
+ {
+ n = lseek (fd, 0, SEEK_CUR);
+ if (n != -1)
+ {
+ avail = statBuffer.st_size - n;
+ return avail;
+ }
+ }
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+
+#elif defined(HAVE_SELECT)
+
+ jint avail = 0;
+ fd_set filedescriptset;
+ struct timeval tv;
+
+ FD_ZERO (&filedescriptset);
+ FD_SET (fd,&filedescriptset);
+ memset (&tv, 0, sizeof(tv));
+
+ switch (select (fd+1, &filedescriptset, NULL, NULL, &tv))
+ {
+ case -1:
+ break;
+ case 0:
+ avail = 0;
+ return avail;
+ default:
+ avail = 1;
+ return avail;
+ }
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+
+#else
+
+ JCL_ThrowException (env, IO_EXCEPTION, "No native method for available");
+
+#endif
+}
+
+
+enum FileChannel_mode {
+ CPNIO_READ = 1,
+ CPNIO_WRITE = 2,
+ CPNIO_APPEND = 4,
+ CPNIO_EXCL = 8,
+ CPNIO_SYNC = 16,
+ CPNIO_DSYNC = 32
+};
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: open
+ * Signature: (Ljava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_open (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jstring path, jint mode)
+{
+ int nmode = 0;
+ int ret;
+ const char *npath;
+
+ if ((mode & CPNIO_READ) && (mode & CPNIO_WRITE))
+ nmode = O_RDWR;
+ else if (mode & CPNIO_WRITE)
+ nmode = O_WRONLY;
+ else
+ nmode = O_RDONLY;
+
+ nmode = (nmode
+ | ((nmode == O_RDWR || nmode == O_WRONLY) ? O_CREAT : 0)
+ | ((mode & CPNIO_APPEND) ? O_APPEND :
+ ((nmode == O_WRONLY) ? O_TRUNC : 0))
+ | ((mode & CPNIO_EXCL) ? O_EXCL : 0)
+ | ((mode & CPNIO_SYNC) ? O_SYNC : 0));
+
+ npath = JCL_jstring_to_cstring (env, path);
+
+/* NIODBG("path: %s; mode: %x", npath, nmode); */
+
+ ret = open (npath, nmode, 0666);
+
+/* NIODBG("ret: %d\n", ret); */
+
+ JCL_free_cstring (env, path, npath);
+
+ if (-1 == ret)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+
+ return ret;
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: position
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_VMChannel_position (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+#ifdef HAVE_LSEEK
+ off_t ret;
+
+ ret = lseek (fd, 0, SEEK_CUR);
+
+ if (-1 == ret)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+
+ return (jlong) ret;
+#else
+ JCL_ThrowException (env, IO_EXCEPTION, "position not supported");
+ return -1;
+#endif /* HAVE_LSEEK */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: seek
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_seek (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jlong pos)
+{
+#ifdef HAVE_LSEEK
+ if (lseek (fd, (off_t) pos, SEEK_SET) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+#else
+ JCL_ThrowException (env, IO_EXCEPTION, "seek not supported");
+#endif /* HAVE_LSEEK */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: truncate
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_truncate (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jlong len)
+{
+#if defined(HAVE_FTRUNCATE) && defined(HAVE_LSEEK)
+ off_t pos = lseek (fd, 0, SEEK_CUR);
+ if (pos == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return;
+ }
+ if (ftruncate (fd, (off_t) len) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return;
+ }
+ if (pos > len)
+ {
+ if (lseek (fd, len, SEEK_SET) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+#else
+ JCL_ThrowException (env, IO_EXCEPTION, "truncate not supported");
+#endif /* HAVE_FTRUNCATE && HAVE_LSEEK */
+}
+
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: lock
+ * Signature: (IJJZZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_VMChannel_lock (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jlong pos, jlong len,
+ jboolean shared, jboolean wait)
+{
+#if HAVE_FCNTL
+ struct flock fl;
+
+ fl.l_start = (off_t) pos;
+ /* Long.MAX_VALUE means lock everything possible starting at pos. */
+ if (len == 9223372036854775807LL)
+ fl.l_len = 0;
+ else
+ fl.l_len = (off_t) len;
+ fl.l_pid = getpid ();
+ fl.l_type = (shared ? F_RDLCK : F_WRLCK);
+ fl.l_whence = SEEK_SET;
+
+ if (cpnio_fcntl (fd, (wait ? F_SETLKW : F_SETLK), (long) &fl) == -1)
+ {
+ if (errno != EAGAIN)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+#else
+ JCL_ThrowException (env, IO_EXCEPTION, "lock not supported");
+ return JNI_FALSE;
+#endif /* HAVE_FCNTL */
+}
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: unlock
+ * Signature: (IJJ)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_unlock (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jlong pos, jlong len)
+{
+#if HAVE_FCNTL
+ struct flock fl;
+
+ fl.l_start = (off_t) pos;
+ fl.l_len = (off_t) len;
+ fl.l_pid = getpid ();
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+
+ if (cpnio_fcntl (fd, F_SETLK, (long) &fl) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+#else
+ JCL_ThrowException (env, IO_EXCEPTION, "unlock not supported");
+#endif /* HAVE_FCNTL */
+}
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: size
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_VMChannel_size (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+#ifdef HAVE_FSTAT
+ struct stat st;
+
+ if (fstat (fd, &st) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+
+ return (jlong) st.st_size;
+#else
+ JCL_ThrowException (env, IO_EXCEPTION, "size not supported");
+ return 0;
+#endif
+}
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: map
+ * Signature: (ICJI)Lgnu/classpath/Pointer;
+ */
+JNIEXPORT jobject JNICALL
+Java_gnu_java_nio_VMChannel_map (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jint fd, jchar mode, jlong position, jint size)
+{
+#ifdef HAVE_MMAP
+ jclass MappedByteBufferImpl_class;
+ jmethodID MappedByteBufferImpl_init = NULL;
+ jobject Pointer_instance;
+ volatile jobject buffer;
+ long pagesize;
+ int prot, flags;
+ void *p;
+ void *address;
+
+/* NIODBG("fd: %d; mode: %x; position: %lld; size: %d", */
+/* fd, mode, position, size); */
+
+ /* FIXME: should we just assume we're on an OS modern enough to
+ have 'sysconf'? And not check for 'getpagesize'? */
+#if defined(HAVE_GETPAGESIZE)
+ pagesize = getpagesize ();
+#elif defined(HAVE_SYSCONF)
+ pagesize = sysconf (_SC_PAGESIZE);
+#else
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "can't determine memory page size");
+ return NULL;
+#endif /* HAVE_GETPAGESIZE/HAVE_SYSCONF */
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ prot = PROT_READ;
+ if (mode == '+' || mode == 'c')
+ {
+ /* When writing we need to make sure the file is big enough,
+ otherwise the result of mmap is undefined. */
+ struct stat st;
+ if (fstat (fd, &st) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return NULL;
+ }
+ if (position + size > st.st_size)
+ {
+ if (ftruncate(fd, position + size) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return NULL;
+ }
+ }
+ prot |= PROT_WRITE;
+ }
+
+ flags = (mode == 'c' ? MAP_PRIVATE : MAP_SHARED);
+ p = mmap (NULL, (size_t) ALIGN_UP (size, pagesize), prot, flags,
+ fd, ALIGN_DOWN (position, pagesize));
+ if (p == MAP_FAILED)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return NULL;
+ }
+
+ /* Unalign the mapped value back up, since we aligned offset
+ down to a multiple of the page size. */
+ address = (void *) ((char *) p + (position % pagesize));
+
+ Pointer_instance = JCL_NewRawDataObject(env, address);
+
+ MappedByteBufferImpl_class = (*env)->FindClass (env,
+ "java/nio/MappedByteBufferImpl");
+ if (MappedByteBufferImpl_class != NULL)
+ {
+ MappedByteBufferImpl_init =
+ (*env)->GetMethodID (env, MappedByteBufferImpl_class,
+ "<init>", "(Lgnu/classpath/Pointer;IZ)V");
+ }
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ munmap (p, ALIGN_UP (size, pagesize));
+ return NULL;
+ }
+ if (MappedByteBufferImpl_init == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "could not get MappedByteBufferImpl constructor");
+ munmap (p, ALIGN_UP (size, pagesize));
+ return NULL;
+ }
+
+ buffer = (*env)->NewObject (env, MappedByteBufferImpl_class,
+ MappedByteBufferImpl_init, Pointer_instance,
+ (jint) size, mode == 'r');
+ return buffer;
+#else
+ (void) fd;
+ (void) mode;
+ (void) position;
+ (void) size;
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "memory-mapped files not implemented");
+ return 0;
+#endif /* HAVE_MMAP */
+}
+
+/*
+ * Class: gnu_java_nio_VMChannel
+ * Method: flush
+ * Signature: (IZ)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_VMChannel_flush (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jboolean metadata __attribute__((unused)))
+{
+#ifdef HAVE_FSYNC
+ /* XXX blocking? */
+ if (fsync (fd) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+#else
+ JCL_ThrowException (env, IO_EXCEPTION, "flush not implemented");
+ return JNI_TRUE;
+#endif /* HAVE_FSYNC */
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c
new file mode 100644
index 000000000..cbaaa0834
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c
@@ -0,0 +1,83 @@
+/* gnu_java_nio_VMPipe.c - Native methods for PipeImpl class
+ Copyright (C) 2004 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 <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "gnu_java_nio_VMPipe.h"
+
+#define IO_EXCEPTION "java/io/IOException"
+
+/*
+ * Class: gnu_java_nio_VMPipe
+ * Method: pipe0
+ * Signature: ()[I
+ */
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_nio_VMPipe_pipe0 (JNIEnv *env,
+ jclass c __attribute__((unused)))
+{
+ int fd[2];
+ jintArray array;
+ jint* elem;
+ int ret;
+
+ /* FIXME: autoconf this? */
+ ret = pipe (fd);
+
+ if (ret == -1)
+ {
+ JCL_ThrowException (env, "java/io/IOException", strerror (errno));
+ return NULL;
+ }
+
+ array = (*env)->NewIntArray (env, 2);
+ elem = (*env)->GetIntArrayElements (env, array, NULL);
+ elem[0] = fd[0];
+ elem[1] = fd[1];
+ (*env)->ReleaseIntArrayElements (env, array, elem, 0);
+ return array;
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c
new file mode 100644
index 000000000..19a6f244d
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c
@@ -0,0 +1,303 @@
+/* gnu_java_nio_VMSelector.c - Native methods for SelectorImpl class
+ Copyright (C) 2004, 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. */
+
+#include "config.h"
+
+/* <sys/types.h> needs to be included on OSX before <sys/select.h> */
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#if defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+#include <sys/time.h>
+
+#include <string.h>
+
+#include <errno.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "gnu_java_nio_VMSelector.h"
+
+/* Amount of characters in the error message buffer for strerror_r. */
+#define BUF_SIZE 250
+
+void helper_put_filedescriptors (JNIEnv *, jintArray, fd_set *, int *);
+
+void helper_get_filedescriptors (JNIEnv *, jintArray *, fd_set *);
+
+void helper_reset (JNIEnv *, jintArray *);
+
+int
+helper_select (JNIEnv *, jclass, jmethodID,
+ int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+void
+helper_put_filedescriptors (JNIEnv * env, jintArray fdArray, fd_set * fds,
+ int *max_fd)
+{
+ jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
+ int size = (*env)->GetArrayLength (env, fdArray);
+ int index, fd;
+
+ for (index = 0; index < size; index++)
+ {
+ fd = tmpFDArray[index];
+
+ if (fd > 0)
+ {
+ FD_SET (tmpFDArray[index], fds);
+
+ if (tmpFDArray[index] > (*max_fd))
+ (*max_fd) = tmpFDArray[index];
+ }
+ }
+}
+
+void
+helper_get_filedescriptors (JNIEnv * env, jintArray * fdArray, fd_set * fds)
+{
+ jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
+ int size = (*env)->GetArrayLength (env, fdArray);
+ int index, fd;
+
+ for (index = 0; index < size; index++)
+ {
+ fd = tmpFDArray[index];
+ if (fd < 0 || !FD_ISSET (fd, fds))
+ tmpFDArray[index] = 0;
+ }
+}
+
+void
+helper_reset (JNIEnv * env, jintArray * fdArray)
+{
+ jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
+ int size = (*env)->GetArrayLength (env, fdArray);
+ int index;
+
+ for (index = 0; index < size; index++)
+ tmpFDArray[index] = 0;
+}
+
+/* A wrapper for select() which ignores EINTR.
+ * Taken from gclib's posix.cc
+ */
+int
+helper_select (JNIEnv * env, jclass thread_class,
+ jmethodID thread_interrupted, int n, fd_set * readfds,
+ fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)
+{
+#ifdef HAVE_SYS_SELECT_H
+ /* If we have a timeout, compute the absolute ending time. */
+ struct timeval end, delay, after;
+ int r;
+
+ if (timeout)
+ {
+ gettimeofday (&end, NULL);
+
+ end.tv_usec += timeout->tv_usec;
+
+ if (end.tv_usec >= 1000000)
+ {
+ ++end.tv_sec;
+ end.tv_usec -= 1000000;
+ }
+
+ end.tv_sec += timeout->tv_sec;
+ delay = *timeout;
+ }
+ else
+ {
+ /* Placate compiler. */
+ delay.tv_sec = delay.tv_usec = 0;
+ }
+
+ while (1)
+ {
+ r = select (n, readfds, writefds, exceptfds, timeout ? &delay : NULL);
+
+ if (r < 0 && errno != EINTR)
+ return -errno;
+ else if (r >= 0)
+ return r;
+
+ /* Here we know we got EINTR. */
+ if ((*env)->
+ CallStaticBooleanMethod (env, thread_class, thread_interrupted))
+ {
+ return -EINTR;
+ }
+
+ if (timeout)
+ {
+ gettimeofday (&after, NULL);
+
+ /* Now compute new timeout argument. */
+ delay.tv_usec = end.tv_usec - after.tv_usec;
+ delay.tv_sec = end.tv_sec - after.tv_sec;
+
+ if (delay.tv_usec < 0)
+ {
+ --delay.tv_sec;
+ delay.tv_usec += 1000000;
+ }
+
+ if (delay.tv_sec < 0)
+ {
+ /* We assume that the user wants a valid select() call
+ * more than precise timing. So if we get a series of
+ * EINTR we just keep trying with delay 0 until we get a
+ * valid result.
+ */
+ delay.tv_sec = 0;
+ }
+ }
+ }
+#else /* HAVE_SYS_SELECT_H */
+ return 0;
+#endif
+
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMSelector_select (JNIEnv * env,
+ jclass obj __attribute__ ((__unused__)),
+ jintArray read,
+ jintArray write,
+ jintArray except, jlong timeout)
+{
+ jint result;
+ jclass thread_class = (*env)->FindClass (env, "java/lang/Thread");
+ jmethodID thread_current_thread =
+ (*env)->GetStaticMethodID (env, thread_class, "currentThread",
+ "()Ljava/lang/Thread;");
+ jmethodID thread_interrupt =
+ (*env)->GetMethodID (env, thread_class, "interrupt", "()V");
+ jmethodID thread_interrupted =
+ (*env)->GetStaticMethodID (env, thread_class, "interrupted", "()Z");
+ jobject current_thread;
+ int max_fd = 0;
+ fd_set read_fds;
+ fd_set write_fds;
+ fd_set except_fds;
+ struct timeval real_time_data;
+ struct timeval *time_data = NULL;
+ char *message;
+
+ /* If a legal timeout value isn't given, use NULL.
+ * This means an infinite timeout. The specification
+ * also says that a zero timeout should be treated
+ * as infinite. Otherwise (if the timeout value is legal),
+ * fill our timeval struct and use it for the select.
+ */
+ if (timeout > 0)
+ {
+ real_time_data.tv_sec = timeout / 1000;
+ real_time_data.tv_usec = (timeout % 1000) * 1000;
+ time_data = &real_time_data;
+ }
+
+ /* Reset all fd_set structures */
+ FD_ZERO (&read_fds);
+ FD_ZERO (&write_fds);
+ FD_ZERO (&except_fds);
+
+ /* Fill the fd_set data structures for the _Jv_select() call. */
+ helper_put_filedescriptors (env, read, &read_fds, &max_fd);
+ helper_put_filedescriptors (env, write, &write_fds, &max_fd);
+ helper_put_filedescriptors (env, except, &except_fds, &max_fd);
+
+ /* Actually do the select */
+ result =
+ helper_select (env, thread_class, thread_interrupted, max_fd + 1,
+ &read_fds, &write_fds, &except_fds, time_data);
+
+ if (result == -EINTR)
+ {
+ /* The behavior of JRE 1.4.1 is that no exception is thrown
+ * when the thread is interrupted, but the thread's interrupt
+ * status is set. Clear all of our select sets and return 0,
+ * indicating that nothing was selected.
+ */
+ current_thread =
+ (*env)->CallStaticObjectMethod (env, thread_class,
+ thread_current_thread);
+ (*env)->CallVoidMethod (env, current_thread, thread_interrupt);
+
+ helper_reset (env, read);
+ helper_reset (env, write);
+ helper_reset (env, except);
+
+ return 0;
+ }
+
+ if (result < 0)
+ {
+#if defined(HAVE_STRERROR_R)
+ char message_buf[BUF_SIZE+1];
+ int errorcode = -result;
+
+ if (strerror_r (errorcode, message_buf, BUF_SIZE))
+ {
+ /* This would mean that message_buf was to small
+ * to hold the error message.
+ */
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Not enough space in message buffer.");
+ return 0;
+ }
+
+ message = message_buf;
+#else
+ message = strerror(errno);
+#endif
+
+ JCL_ThrowException (env, "java/io/IOException", message);
+ return 0;
+ }
+
+ /* Set the file descriptors according to the values returned from select(). */
+ helper_get_filedescriptors (env, read, &read_fds);
+ helper_get_filedescriptors (env, write, &write_fds);
+ helper_get_filedescriptors (env, except, &except_fds);
+
+ return result;
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c
new file mode 100644
index 000000000..248a948c3
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c
@@ -0,0 +1,208 @@
+/* gnu_java_nio_charset_iconv_IconvDecoder.c --
+ Copyright (C) 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. */
+
+#include <config.h>
+#include <jcl.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+#if defined(HAVE_ICONV)
+#include <iconv.h>
+#endif
+
+#include "gnu_java_nio_charset_iconv_IconvDecoder.h"
+
+#if defined(HAVE_ICONV)
+static void createRawData (JNIEnv * env, jobject obj, void *ptr);
+static void *getData (JNIEnv * env, jobject obj);
+
+static jfieldID infid = NULL;
+static jfieldID outfid = NULL;
+#endif
+
+/* Union used for type punning. */
+union char_union
+{
+ jbyte **jb;
+ jchar **jc;
+ char **c;
+};
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvDecoder_openIconv (JNIEnv * env UNUSED,
+ jobject obj UNUSED,
+ jstring jname UNUSED)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ jclass cls;
+
+ const char *name = JCL_jstring_to_cstring (env, jname);
+ if (name == NULL)
+ return;
+
+ /* Cache fieldIDs for use in decode function. */
+ if (infid == NULL || outfid == NULL)
+ {
+ cls = (*env)->GetObjectClass (env, obj);
+ infid = (*env)->GetFieldID (env, cls, "inremaining", "I");
+ assert (infid != 0);
+ outfid = (*env)->GetFieldID (env, cls, "outremaining", "I");
+ assert (outfid != 0);
+ }
+
+ /* to java from "name", native java format depends on endianness */
+#ifdef WORDS_BIGENDIAN
+ iconv_object = iconv_open ("UTF-16BE", name);
+#else
+ iconv_object = iconv_open ("UTF-16LE", name);
+#endif
+
+ JCL_free_cstring (env, jname, name);
+ if ((long) iconv_object == -1L)
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Charset not available");
+ return;
+ }
+ createRawData (env, obj, (void *) iconv_object);
+#else
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "iconv not available");
+#endif
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_charset_iconv_IconvDecoder_decode (JNIEnv * env UNUSED,
+ jobject obj UNUSED,
+ jbyteArray inArr UNUSED,
+ jcharArray outArr UNUSED,
+ jint posIn UNUSED,
+ jint remIn UNUSED,
+ jint posOut UNUSED,
+ jint remOut UNUSED)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object = getData (env, obj);
+ size_t retval;
+ union char_union in, out;
+ jbyte *input, *inputcopy;
+ jchar *output, *outputcopy;
+ size_t lenIn = (size_t) remIn;
+ size_t lenOut = (size_t) remOut * 2;
+
+ inputcopy = input = (*env)->GetByteArrayElements (env, inArr, 0);
+ outputcopy = output = (*env)->GetCharArrayElements (env, outArr, 0);
+
+ input += posIn;
+ output += posOut;
+
+ in.jb = &input;
+ out.jc = &output;
+ retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn,
+ out.c, &lenOut);
+
+ /* XXX: Do we need to relase the input array? It's not modified. */
+ (*env)->ReleaseByteArrayElements (env, inArr, inputcopy, 0);
+ (*env)->ReleaseCharArrayElements (env, outArr, outputcopy, 0);
+
+ if (retval == (size_t) (-1))
+ {
+ if (errno == EILSEQ)
+ retval = 1;
+ else
+ retval = 0;
+ }
+ else
+ retval = 0;
+
+ (*env)->SetIntField (env, obj, infid, (jint) lenIn);
+ (*env)->SetIntField (env, obj, outfid, (jint) (lenOut >> 1));
+
+ return (jint) retval;
+#else
+ return -1;
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvDecoder_closeIconv (JNIEnv * env UNUSED,
+ jobject obj UNUSED)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ iconv_object = getData (env, obj);
+ iconv_close (iconv_object);
+#endif
+}
+
+
+#if defined(HAVE_ICONV)
+static void
+createRawData (JNIEnv * env, jobject obj, void *ptr)
+{
+ jclass cls;
+ jobject data;
+ jfieldID data_fid;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/Pointer;");
+ assert (data_fid != 0);
+
+ data = JCL_NewRawDataObject(env, ptr);
+
+ (*env)->SetObjectField (env, obj, data_fid, data);
+}
+
+static void *
+getData (JNIEnv * env, jobject obj)
+{
+ jclass cls;
+ jfieldID data_fid;
+ jobject data;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/Pointer;");
+ assert (data_fid != 0);
+ data = (*env)->GetObjectField (env, obj, data_fid);
+
+ return JCL_GetRawData(env, data);
+}
+#endif
+
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c
new file mode 100644
index 000000000..54fd17286
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c
@@ -0,0 +1,208 @@
+/* gnu_java_nio_charset_iconv_IconvEncoder.c --
+ Copyright (C) 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. */
+
+#include <config.h>
+#include <jcl.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+#if defined(HAVE_ICONV)
+#include <iconv.h>
+#endif
+
+#include "gnu_java_nio_charset_iconv_IconvEncoder.h"
+
+
+#if defined(HAVE_ICONV)
+static void createRawData (JNIEnv * env, jobject obj, void *ptr);
+static void *getData (JNIEnv * env, jobject obj);
+
+static jfieldID infid = NULL;
+static jfieldID outfid = NULL;
+#endif
+
+/* Union used for type punning. */
+union char_union
+{
+ jbyte **jb;
+ jchar **jc;
+ char **c;
+};
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvEncoder_openIconv (JNIEnv * env UNUSED,
+ jobject obj UNUSED,
+ jstring jname UNUSED)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ jclass cls;
+
+ const char *name = JCL_jstring_to_cstring (env, jname);
+ if (name == NULL)
+ return;
+
+ /* Cache fieldIDs for use in encode function. */
+ if (infid == NULL || outfid == NULL)
+ {
+ cls = (*env)->GetObjectClass (env, obj);
+ infid = (*env)->GetFieldID (env, cls, "inremaining", "I");
+ assert (infid != 0);
+ outfid = (*env)->GetFieldID (env, cls, "outremaining", "I");
+ assert (outfid != 0);
+ }
+
+ /* to "name" from java, native java format depends on endianness */
+#ifdef WORDS_BIGENDIAN
+ iconv_object = iconv_open (name, "UTF-16BE");
+#else
+ iconv_object = iconv_open (name, "UTF-16LE");
+#endif
+
+ JCL_free_cstring (env, jname, name);
+ if ((long) iconv_object == -1L)
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Charset not available");
+ return;
+ }
+ createRawData (env, obj, (void *) iconv_object);
+#else
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "iconv not available");
+#endif
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_charset_iconv_IconvEncoder_encode (JNIEnv * env UNUSED,
+ jobject obj UNUSED,
+ jcharArray inArr UNUSED,
+ jbyteArray outArr UNUSED,
+ jint posIn UNUSED,
+ jint remIn UNUSED,
+ jint posOut UNUSED,
+ jint remOut UNUSED)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object = getData (env, obj);
+ size_t retval;
+ union char_union in, out;
+ jchar *input, *inputcopy;
+ jbyte *output, *outputcopy;
+ size_t lenIn = (size_t) remIn * 2;
+ size_t lenOut = (size_t) remOut;
+
+ inputcopy = input = (*env)->GetCharArrayElements (env, inArr, 0);
+ outputcopy = output = (*env)->GetByteArrayElements (env, outArr, 0);
+
+ input += posIn;
+ output += posOut;
+
+ in.jc = &input;
+ out.jb = &output;
+ retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn,
+ out.c, &lenOut);
+
+ /* XXX: Do we need to relase the input array? It's not modified. */
+ (*env)->ReleaseCharArrayElements (env, inArr, inputcopy, 0);
+ (*env)->ReleaseByteArrayElements (env, outArr, outputcopy, 0);
+
+ if (retval == (size_t) (-1))
+ {
+ if (errno == EILSEQ || errno == EINVAL)
+ retval = 1;
+ else
+ retval = 0;
+ }
+ else
+ retval = 0;
+
+ (*env)->SetIntField (env, obj, infid, (jint) (lenIn >> 1));
+ (*env)->SetIntField (env, obj, outfid, (jint) lenOut);
+
+ return (jint) retval;
+#else
+ return -1;
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvEncoder_closeIconv (JNIEnv * env UNUSED,
+ jobject obj UNUSED)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ iconv_object = getData (env, obj);
+ iconv_close (iconv_object);
+#endif
+}
+
+
+#if defined(HAVE_ICONV)
+static void
+createRawData (JNIEnv * env, jobject obj, void *ptr)
+{
+ jclass cls;
+ jobject data;
+ jfieldID data_fid;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/Pointer;");
+ assert (data_fid != 0);
+
+ data = JCL_NewRawDataObject (env, ptr);
+
+ (*env)->SetObjectField (env, obj, data_fid, data);
+}
+
+static void *
+getData (JNIEnv * env, jobject obj)
+{
+ jclass cls;
+ jfieldID data_fid;
+ jobject data;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/Pointer;");
+ assert (data_fid != 0);
+ data = (*env)->GetObjectField (env, obj, data_fid);
+
+ return JCL_GetRawData(env, data);
+}
+#endif
diff --git a/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c b/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c
new file mode 100644
index 000000000..2a87d2950
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c
@@ -0,0 +1,241 @@
+/* java_nio_MappedByteBufferImpl.c - Native methods for MappedByteBufferImpl
+ Copyright (C) 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. */
+
+#include <config.h>
+#include <errno.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "java_nio_MappedByteBufferImpl.h"
+
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif /* HAVE_SYS_MMAN_H */
+
+#define IO_EXCEPTION "java/io/IOException"
+
+/* FIXME these are defined in gnu_java_nio_channels_FileChannelImpl
+ too; should be someplace common. */
+#define ALIGN_DOWN(p,s) ((jpointer)(p) - ((jpointer)(p) % (s)))
+#define ALIGN_UP(p,s) ((jpointer)(p) + ((s) - ((jpointer)(p) % (s))))
+
+/**
+ * Returns the memory page size of this platform.
+ *
+ * \return The page size.
+ */
+static long
+get_pagesize (void)
+{
+ /* FIXME can we just try HAVE_SYSCONF? */
+#if defined(HAVE_GETPAGESIZE)
+ return getpagesize ();
+#elif defined (HAVE_SYSCONF)
+ return sysconf (_SC_PAGESIZE);
+#endif /* HAVE_GETPAGESIZE / HAVE_SYSCONF */
+}
+
+/**
+ * Retrieve the 'address' and 'cap' (the mapped size) fields of this
+ * buffer.
+ *
+ * This function will align the address down to the nearest page
+ * boundary, and the size up to the nearest page boundary. Thus, it is
+ * safe to use these values in 'mman' functions.
+ *
+ * \param env The JNI environment pointer.
+ * \param this The MappedByteBufferImpl instance.
+ * \param address A pointer to where the actual pointer should be
+ * stored.
+ * \param size A pointer to where the mapped region's size should be
+ * stored
+ */
+static void
+get_raw_values (JNIEnv *env, jobject this, void **address, size_t *size)
+{
+ const long pagesize = get_pagesize ();
+ jfieldID MappedByteBufferImpl_address;
+ jfieldID MappedByteBufferImpl_size;
+ jobject MappedByteBufferImpl_address_value = NULL;
+
+ *address = NULL;
+ /* 'address' is declared in java.nio.Buffer */
+ MappedByteBufferImpl_address
+ = (*env)->GetFieldID (env, (*env)->GetObjectClass (env, this),
+ "address", "Lgnu/classpath/Pointer;");
+ /* 'cap' -- likewise, the capacity */
+ MappedByteBufferImpl_size
+ = (*env)->GetFieldID (env, (*env)->GetObjectClass (env, this),
+ "cap", "I");
+ if (MappedByteBufferImpl_address != NULL)
+ {
+ MappedByteBufferImpl_address_value =
+ (*env)->GetObjectField (env, this, MappedByteBufferImpl_address);
+ }
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ if (MappedByteBufferImpl_address_value == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/NullPointerException",
+ "mapped address is NULL");
+ return;
+ }
+
+ *address = (void *)
+ ALIGN_DOWN (JCL_GetRawData (env, MappedByteBufferImpl_address_value), pagesize);
+ *size = (size_t)
+ ALIGN_UP ((*env)->GetIntField (env, this, MappedByteBufferImpl_size),
+ pagesize);
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBufferImpl_unmapImpl (JNIEnv *env, jobject this)
+{
+#ifdef HAVE_MUNMAP
+ void *address;
+ size_t size;
+
+ get_raw_values (env, this, &address, &size);
+
+ if (address == NULL)
+ return;
+
+ if (munmap (address, size) != 0)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return;
+ }
+#else
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "unmapping files not implemented");
+#endif /* HAVE_MUNMAP */
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_nio_MappedByteBufferImpl_isLoadedImpl (JNIEnv * env, jobject this)
+{
+#ifdef HAVE_MINCORE
+ void *address;
+ size_t size;
+ char *vec;
+ size_t count, i;
+ const long pagesize = get_pagesize ();
+
+ /*
+ * FIXME on Darwin this does not work if the mapped region is
+ * exactly one page long; i.e., 'mincore' tells us it isn't loaded.
+ */
+ get_raw_values (env, this, &address, &size);
+ if (address == NULL)
+ return JNI_FALSE;
+ count = (size_t) ((size + pagesize - 1) / pagesize);
+ vec = (char *) malloc (count * sizeof (unsigned char));
+
+ /*
+ * Darwin (and BSD?) define argument 3 of 'mincore' to be 'char *',
+ * while GNU libc defines it to be 'unsigned char *'. Casting the
+ * argument to 'void *' fixes this, but not with C++. So you might
+ * be SOL if you compile this with g++ (!) on GNU with -Werror.
+ */
+#ifdef __cplusplus
+ if (mincore (address, size, vec) != 0)
+#else
+ if (mincore (address, size, (void *) vec) != 0)
+#endif /* __cplusplus */
+ {
+ free (vec);
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ return JNI_FALSE;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if ((vec[i] & 1) == 0)
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+#else
+ return JNI_FALSE;
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBufferImpl_loadImpl (JNIEnv *env, jobject this)
+{
+#ifdef HAVE_MADVISE
+ void *address;
+ size_t size;
+
+ get_raw_values (env, this, &address, &size);
+ if (address == NULL)
+ return;
+
+ madvise (address, size, MADV_WILLNEED);
+#else
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "forcing mapped files into core not implemented");
+#endif /* HAVE_MADVISE */
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBufferImpl_forceImpl (JNIEnv *env, jobject this)
+{
+#ifdef HAVE_MSYNC
+ void *address;
+ size_t size;
+
+ get_raw_values (env, this, &address, &size);
+
+ if (address == NULL)
+ return;
+
+ /* FIXME: is using MS_SYNC ok? Should we use MS_INVALIDATE? */
+ if (msync (address, size, MS_SYNC) != 0)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+#else
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "forcing mapped files to disk not implemented");
+#endif /* HAVE_MSYNC */
+}
diff --git a/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c b/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c
new file mode 100644
index 000000000..bfee7e9dc
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c
@@ -0,0 +1,130 @@
+/* java_nio_VMDirectByteBuffer.c - Native methods for VMDirectByteBuffer
+ Copyright (C) 2004, 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. */
+
+#include <config.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "java_nio_VMDirectByteBuffer.h"
+
+JNIEXPORT jobject JNICALL
+Java_java_nio_VMDirectByteBuffer_allocate
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), jint capacity)
+{
+ void *buffer;
+
+ buffer = malloc (capacity);
+
+ if (buffer == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/OutOfMemoryError",
+ "unable to allocate memory for direct byte buffer");
+ return 0;
+ }
+
+ memset (buffer, 0, capacity);
+
+ return JCL_NewRawDataObject (env, buffer);
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_free
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), jobject address)
+{
+ free (JCL_GetRawData (env, address));
+}
+
+JNIEXPORT jbyte JNICALL
+Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_Pointer_2I
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint index)
+{
+ return ((jbyte *) JCL_GetRawData (env, address))[index];
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_put__Lgnu_classpath_Pointer_2IB
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint index, jbyte value)
+{
+ jbyte *pointer = (jbyte *) JCL_GetRawData (env, address) + index;
+ *pointer = value;
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_Pointer_2I_3BII
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint index, jbyteArray dst, jint dst_offset, jint dst_len)
+{
+ jbyte *src = (jbyte *) JCL_GetRawData (env, address) + index;
+ jbyte *_dst = (*env)->GetByteArrayElements (env, dst, NULL);
+ memcpy (_dst + dst_offset, src, dst_len);
+ (*env)->ReleaseByteArrayElements (env, dst, _dst, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_put__Lgnu_classpath_Pointer_2I_3BII
+ (JNIEnv *env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint index, jbyteArray src, jint src_offset, jint src_len)
+{
+ jbyte *_src = (*env)->GetByteArrayElements (env, src, NULL);
+ jbyte *dst = (jbyte *)JCL_GetRawData (env, address);
+ memcpy (dst + index, _src + src_offset, src_len);
+ (*env)->ReleaseByteArrayElements (env, src, _src, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_shiftDown
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint dst_offset, jint src_offset, jint count)
+{
+ jbyte *dst = (jbyte *) JCL_GetRawData (env, address) + dst_offset;
+ jbyte *src = (jbyte *) JCL_GetRawData (env, address) + src_offset;
+ memmove (dst, src, count);
+}
+
+JNIEXPORT jobject JNICALL
+Java_java_nio_VMDirectByteBuffer_adjustAddress
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint offset)
+{
+ return JCL_NewRawDataObject (env, (jbyte *) JCL_GetRawData (env, address) + offset);
+}
diff --git a/libjava/classpath/native/jni/java-nio/javanio.c b/libjava/classpath/native/jni/java-nio/javanio.c
new file mode 100644
index 000000000..a7018b347
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/javanio.c
@@ -0,0 +1,144 @@
+/* javanio.c -- implementations of functions in javanio.h.
+ 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. */
+
+
+/*
+ * Note, because these functions are trivial, and should be inlined,
+ * we include this file in the header, and do not compile it.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <sys/uio.h>
+
+CPNIO_EXPORT ssize_t
+cpnio_read (int fd, void *buf, size_t nbytes)
+{
+ return read (fd, buf, nbytes);
+}
+
+CPNIO_EXPORT ssize_t
+cpnio_readv (int fd, const struct iovec *iov, int iovcnt)
+{
+ return readv (fd, iov, iovcnt);
+}
+
+CPNIO_EXPORT ssize_t
+cpnio_write (int fd, const void *buf, size_t nbytes)
+{
+ return write (fd, buf, nbytes);
+}
+
+CPNIO_EXPORT ssize_t
+cpnio_writev (int fd, const struct iovec *iov, size_t iovcnt)
+{
+ return writev (fd, iov, iovcnt);
+}
+
+CPNIO_EXPORT int
+cpnio_socket (int domain, int type, int protocol)
+{
+ return socket (domain, type, protocol);
+}
+
+CPNIO_EXPORT int
+cpnio_connect (int fd, const struct sockaddr *addr, socklen_t addrlen)
+{
+ return connect (fd, addr, addrlen);
+}
+
+CPNIO_EXPORT int
+cpnio_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ fd_set rset;
+ struct timeval tv;
+ socklen_t tvlen = sizeof(tv);
+ int ret;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ getsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &tvlen);
+ if (tv.tv_sec > 0 || tv.tv_usec > 0)
+ {
+ FD_ZERO(&rset);
+ FD_SET(fd,&rset);
+ ret = select (fd+1,&rset,NULL,NULL,&tv);
+ if (ret == 0)
+ {
+ errno = EAGAIN;
+ return -1;
+ }
+ }
+ return accept (fd, addr, addrlen);
+}
+
+CPNIO_EXPORT ssize_t
+cpnio_sendto (int fd, const void *msg, size_t len, int flags,
+ const struct sockaddr *to, socklen_t tolen)
+{
+ return sendto (fd, msg, len, flags, to, tolen);
+}
+
+CPNIO_EXPORT ssize_t
+cpnio_recvfrom (int fd, void *buf, size_t len, int flags,
+ struct sockaddr *from, socklen_t *fromlen)
+{
+ return recvfrom (fd, buf, len, flags, from, fromlen);
+}
+
+CPNIO_EXPORT int
+cpnio_fcntl (int fd, int cmd, long arg)
+{
+#ifdef HAVE_FCNTL
+ return fcntl (fd, cmd, arg);
+#else
+ errno = ENOSUP;
+ return -1;
+#endif /* HAVE_FCNTL */
+}
+
+CPNIO_EXPORT int
+cpnio_select (int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *excepfds, struct timeval *timeo)
+{
+ return select (nfds, readfds, writefds, excepfds, timeo);
+}
diff --git a/libjava/classpath/native/jni/java-nio/javanio.h b/libjava/classpath/native/jni/java-nio/javanio.h
new file mode 100644
index 000000000..cc31cf3c1
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/javanio.h
@@ -0,0 +1,334 @@
+/* javanio.h -- reference implementation of native functions.
+ 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 __JAVANIO_H__
+#define __JAVANIO_H__
+
+#include <sys/time.h>
+
+/**
+ * This header defines functions that are called by our JNI reference
+ * implementation of java.nio.*. In our reference implementation, these
+ * functions map exactly to their counterparts in POSIX; in implementations
+ * that can't use these functions directly (such as systems that use user-land
+ * threads, and thus can't call blocking system calls directly) can provide
+ * their own implementations suitable for their system.
+ */
+
+/**
+ * This macro is used in all function prototypes below; if any additional
+ * keywords need to be added to a prototype, declare them in this macro.
+ */
+#define CPNIO_EXPORT static inline
+
+/**
+ * Read bytes from the given file descriptor into the given memory address, which
+ * has sufficient space for NBYTES bytes.
+ *
+ * \param fd The file descriptor to read from.
+ * \param buf The memory address to read bytes into.
+ * \param nbytes The number of bytes available to store in BUF.
+ * \return The number of bytes read, possibly zero, on success; return -1 on failure,
+ * and set ERRNO to an appropriate value.
+ * \see read(2)
+ *
+ * Allowed errno values:
+ * [EBADF] If FD is not a valid file descriptor, or is not open for reading.
+ * [EFAULT] If BUF points outside the process's address space.
+ * [EIO] An I/O error occurrs.
+ * [EINTR] If the read is interrupted by a signal.
+ * [EINVAL] If FD is negative.
+ * [EAGAIN] If FD was marked for non-blocking I/O, and no data were ready to
+ * be read.
+ */
+CPNIO_EXPORT ssize_t cpnio_read (int fd, void *buf, size_t nbytes);
+
+/*
+ * Read bytes from a file descriptor into a sequence of IO buffers.
+ *
+ * The iovec structure is defined as:
+ *
+ * struct iovec {
+ * char *iov_base;
+ * size_t iov_len;
+ * };
+ *
+ * The call to _cp_readv should do a scattering read, where for each struct iovec
+ * in the supplied list, up to IOV_LEN bytes are read into IOV_BASE. The function
+ * returns the total number of bytes read into all supplied buffers.
+ *
+ * \param fd The file descriptor.
+ * \param iov A pointer to the head of a list of iovec structures.
+ * \param iovcnt The number of iovec structures pointed to by IOV.
+ * \return The total number of bytes read accross all buffers, possibly zero. On
+ * error, -1 is returned and ERRNO is set.
+ * \see readv(2)
+ *
+ * Allowed ERRNO values include all of those listed for _cp_read, as well as the
+ * following:
+ * [EINVAL] If IOVCNT overflows the maximum number of iovec structures
+ * this platform supports (usually 16), if any IOV_LEN value
+ * is negative, or if the sum of all IOV_LEN values is too
+ * large to be stored in a ssize_t (usually a 32-bit integer).
+ * [EFAULT] If part of IOV points outside the process's address space.
+ */
+CPNIO_EXPORT ssize_t cpnio_readv (int fd, const struct iovec *iov, int iovcnt);
+
+/*
+ * Write NBYTES bytes from BUF to the file descriptor FD, returning the number
+ * of bytes successfully written.
+ *
+ * \param fd The file descriptor.
+ * \param buf A pointer to the bytes to write.
+ * \param nbytes The maximum number of bytes to write.
+ * \return The number of bytes written to the file descriptor, possibly zero. -1
+ * is returned if an error is encountered, and ERRNO will be set.
+ * \see write(2)
+ *
+ * Allowed ERRNO values:
+ * [EBADF] If FD is not a valid file descriptor or is not open for writing.
+ * [EPIPE] If FD is a pipe, when the other side is disconnected; if FD is a
+ * socket, when the peer is not connected.
+ * [EFBIG] When FD is a file, and writing to it overflows the process's
+ * or the system's maximim file size.
+ * [EFAULT] If the buffer to write points outside the process's address
+ * space.
+ * [EINVAL] If the descriptor FD is negative.
+ * [ENOSPC] If FD is a file, and there is insufficient space on the
+ * filesystem.
+ * [EDQUOT] If FD is a file, and the user's disk quota has been exceeded.
+ * [EIO] If an I/O error occurs.
+ * [EINTR] If the call is interrupted by a signal.
+ * [EAGAIN] If FD is in non-blocking mode, and no bytes could be immediately
+ * written.
+ */
+CPNIO_EXPORT ssize_t cpnio_write (int fd, const void *buf, size_t nbytes);
+
+/*
+ * Write data from a sequence of IOVCNT buffers IOV to a file descriptor FD.
+ *
+ * \param fd The file descriptor.
+ * \param iov The list of buffers to write.
+ * \param iovcnt The number of iovec structures pointed to by IOV.
+ * \return The total number of bytes written from the given buffers, possibly
+ * zero. -1 if an error occurs, and ERRNO will be set.
+ * \see writev(2)
+ *
+ * Allowed ERRNO values include those mentioned in _cp_write, as well as:
+ * [EDESTADDRREQ] If the descriptor is a datagram socket, and the peer is
+ * no longer available.
+ * [EINVAL] If IOVCNT is out of range, if any IOV_LEN value is
+ * negative, or if the sum of all IOVCNT IOV_LEN values
+ * will overflow a ssize_t.
+ * [ENOBUFS] If the mbuf pool is exhausted (???).
+ */
+CPNIO_EXPORT ssize_t cpnio_writev (int fd, const struct iovec *iov, size_t iovcnt);
+
+/**
+ * Open a new, unbound and unconnected socket.
+ *
+ * \param domain The socket domain. Implementations need only handle AF_INET.
+ * \param type The socket type; implementations need only handle types
+ * SOCK_STREAM (for streaming sockets) and SOCK_DGRAM (for datagram sockets).
+ * \param protocol This should always be 0. It can be ignored.
+ * \return A new file descriptor pointing to a newly created socket, or -1 on
+ * error, and ERRNO set.
+ *
+ * Allowed ERRNO values:
+ * [EPROTONOSUPPORT] If TYPE is unrecognized.
+ * [EMFILE] If a new file descriptor cannot be allocated, because
+ * the process's descriptor table is full.
+ * [ENFILE] Likewise, but when the system table is full.
+ * [EACCES] If this operation is not allowed.
+ * [ENOBUFS] If there is not enough buffer space available for the
+ * new socket.
+ */
+CPNIO_EXPORT int cpnio_socket (int domain, int type, int protocol);
+
+/**
+ * Connect a socket to a remote address.
+ *
+ * \param fd The file descriptor of the socket to connect.
+ * \param addr The address to connect to. In practice, this should be
+ * either a `struct sockaddr_in' or a `struct sockaddr_in6'.
+ * \param addrlen The size of the address structure passed by ADDR.
+ * \return Zero if the connect succeeds. -1 on error, and ERRNO should be set.
+ *
+ * Allowed ERRNO values:
+ * [EBADF] If FD is not a valid file descriptor.
+ * [ENOTSOCK] If FD is not a socket descriptor.
+ * [EADDRNOTAVAIL] If ADDR is not available for use to this process.
+ * [EAFNOSUPPORT] If the address family of ADDR is not supported.
+ * [EISCONN] If the socket is already connected.
+ * [ETIMEDOUT] If the connection could not be made in a reasonable
+ * amount of time.
+ * [ECONNREFUSED] If the connection attempt was rejected.
+ * [ENETUNREACH] If the network ADDR is on is unreachable.
+ * [EADDRINUSE] If the address is already in use.
+ * [EFAULT] If ADDR points outside the addressable space.
+ * [EINPROGRESS] If FD is in non-blocking mode, and the connection could
+ * not be completed immediately.
+ * [EALREADY] If FD is in non-blocking mode, and a connection attempt
+ * is still pending.
+ * [EACCESS] If ADDR is the broadcast address, and the socket option
+ * SO_BROADCAST is not set.
+ */
+CPNIO_EXPORT int cpnio_connect (int fd, const struct sockaddr *addr, socklen_t addrlen);
+
+/**
+ * Accept an incoming connection on a socket, returning a new socket for
+ * the connection, and storing the peer address in ADDR.
+ *
+ * \param fd The socket file descriptor.
+ * \param addr The structure to store the peer address in.
+ * \param addrlen The size of the data available in ADDR; upon return, the
+ * number of bytes stored in ADDR will be placed here.
+ * \return The new socket file descriptor, or -1 on error, and ERRNO set.
+ *
+ * Allowed ERRNO values:
+ * [EBADF] If FD is not a valid file descriptor.
+ * [ENOTSOCK] If FD in not a socket descriptor.
+ * [EOPNOTSUPP] If the socket is not a SOCK_STREAM socket.
+ * [EFAULT] If ADDR points outside the process's addressable space.
+ * [EWOULDBLOCK] If the socket is in non-blocking mode, and no connection
+ * attempt is currently ready.
+ * [EMFILE] If the process's descriptor table is full.
+ * [ENFILE] If the system's descriptor table is full.
+ */
+CPNIO_EXPORT int cpnio_accept (int fd, struct sockaddr *addr, socklen_t *addrlen);
+
+/**
+ * Send a datagram to the given address.
+ *
+ * \param fd The socket file descriptor.
+ * \param msg A pointer to the message to send.
+ * \param len The size of the message to send.
+ * \param flags Flags for sending.
+ * \param to The remote address to send the message to.
+ * \param tolen The size of the TO address structure.
+ * \return The number of bytes written, possibly zero, on success. Returns
+ * -1 on failure, and sets ERRNO.
+ * \see sendto(2)
+ *
+ * Allowed ERRNO values:
+ * [EBADF]
+ * [ENOTSOCK]
+ * [EFAULT]
+ * [EMSGSIZE]
+ * [EAGAIN]
+ * [ENOBUFS]
+ * [EACCES]
+ * [EHOSTUNREACH]
+ */
+CPNIO_EXPORT ssize_t cpnio_sendto (int fd, const void *msg, size_t len, int flags,
+ const struct sockaddr *to, socklen_t tolen);
+
+/**
+ * Receive a message on a socket, storing the remote host's address in
+ * FROM.
+ *
+ * \param fd The socket file descriptor.
+ * \param buf The buffer to store received bytes in.
+ * \param flags Flags to control the receive.
+ * \param from Where to store the remote address.
+ * \param fromlen Pointer to the size of FROM; on return, it will contain the
+ * size of the structure placed in FROM.
+ * \return The number of bytes received on success. -1 on error, and ERRNO will
+ * be set.
+ * \see recvfrom(2)
+ *
+ * Allewed ERRNO values:
+ * [EBADF] FD is not a valid file descriptor.
+ * [ENOTCONN] If the socket is stream-oriented, and no prior call to
+ * connect(2) was made.
+ * [ENOTSOCK] FD is not a socket.
+ * [EAGAIN] FD is in non-blocking mode, and no message was
+ * immediately available.
+ * [EINTR] The system call was interrupted by a signal.
+ * [EFAULT] BUF, FROM, or FROMLEN lie outside the process's address
+ * space.
+ */
+CPNIO_EXPORT ssize_t cpnio_recvfrom (int fd, void *buf, size_t len, int flags,
+ struct sockaddr *from, socklen_t *fromlen);
+
+
+/**
+ * Control file descriptor properties.
+ *
+ * \param fd The file descriptor to control.
+ * \param cmd The command to execute.
+ * \param arg The command argument.
+ * \return A value other than -1, specific to CMD. On error, -1 is
+ * returned, and ERRNO is set.
+ *
+ * Allowed ERRNO values:
+ * FIXME
+ */
+CPNIO_EXPORT int cpnio_fcntl (int fd, int cmd, long arg);
+
+
+/**
+ * Select from one of the given file descriptor sets a descriptor that
+ * is ready for the given operation (read, write, etc.).
+ *
+ * \param nfds A value one larger than the largest file
+ * descriptor.
+ * \param readfds A set of file descriptors to select for
+ * readability.
+ * \param writefds A set of file descriptors to select for
+ * writability.
+ * \param exceptfds A set of file descriptors to select for
+ * exceptional conditions.
+ * \param tm The selection timeout.
+ * \return The number of file descriptors selected, possibly zero, or
+ * -1 on error (and with ERRNO set).
+ */
+CPNIO_EXPORT int cpnio_select (int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *tm);
+
+/*
+ * We include the implementation file here, because our reference
+ * implementation is trivial, and the functions are declared extern
+ * inline.
+ *
+ * Implementations that need different implementations of these functions
+ * SHOULD remove this line, and compile javanio.c as a separate unit.
+ */
+#include "javanio.c"
+
+#endif /* __JAVANIO_H__ */