Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement basic server and client unix sockets

  • Loading branch information...
commit 5c2e7fc2f6256ed6fa67ab1ae0c5a518d4e6cf64 1 parent 5e36d7d
Wayne Meissner authored
View
276 nbproject/build-impl.xml
@@ -20,6 +20,13 @@ is divided into following sections:
-->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="enxio-socket-impl">
+ <fail message="Please build using Ant 1.7.1 or higher.">
+ <condition>
+ <not>
+ <antversion atleast="1.7.1"/>
+ </not>
+ </condition>
+ </fail>
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
<!--
======================
@@ -35,22 +42,28 @@ is divided into following sections:
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
</target>
- <target depends="-pre-init,-init-private" name="-init-libraries">
- <property location="./lib/nblibraries.properties" name="libraries.1.path"/>
- <dirname file="${libraries.1.path}" property="libraries.1.dir.nativedirsep"/>
- <pathconvert dirsep="/" property="libraries.1.dir">
- <path path="${libraries.1.dir.nativedirsep}"/>
+ <target name="-pre-init-libraries">
+ <property location="./lib/nblibraries.properties" name="libraries.path"/>
+ <dirname file="${libraries.path}" property="libraries.dir.nativedirsep"/>
+ <pathconvert dirsep="/" property="libraries.dir">
+ <path path="${libraries.dir.nativedirsep}"/>
</pathconvert>
- <basename file="${libraries.1.path}" property="libraries.1.basename" suffix=".properties"/>
- <touch file="${libraries.1.dir}/${libraries.1.basename}-private.properties"/>
- <loadproperties srcfile="${libraries.1.dir}/${libraries.1.basename}-private.properties">
+ <basename file="${libraries.path}" property="libraries.basename" suffix=".properties"/>
+ <available file="${libraries.dir}/${libraries.basename}-private.properties" property="private.properties.available"/>
+ </target>
+ <target depends="-pre-init-libraries" if="private.properties.available" name="-init-private-libraries">
+ <loadproperties encoding="ISO-8859-1" srcfile="${libraries.dir}/${libraries.basename}-private.properties">
<filterchain>
- <replacestring from="$${base}" to="${libraries.1.dir}"/>
+ <replacestring from="$${base}" to="${libraries.dir}"/>
+ <escapeunicode/>
</filterchain>
</loadproperties>
- <loadproperties srcfile="${libraries.1.path}">
+ </target>
+ <target depends="-pre-init,-init-private,-init-private-libraries" name="-init-libraries">
+ <loadproperties encoding="ISO-8859-1" srcfile="${libraries.path}">
<filterchain>
- <replacestring from="$${base}" to="${libraries.1.dir}"/>
+ <replacestring from="$${base}" to="${libraries.dir}"/>
+ <escapeunicode/>
</filterchain>
</loadproperties>
</target>
@@ -67,21 +80,52 @@ is divided into following sections:
</target>
<target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-init-macrodef-property" name="-do-init">
<available file="${manifest.file}" property="manifest.available"/>
- <condition property="manifest.available+main.class">
+ <condition property="main.class.available">
<and>
- <isset property="manifest.available"/>
<isset property="main.class"/>
<not>
<equals arg1="${main.class}" arg2="" trim="true"/>
</not>
</and>
</condition>
+ <condition property="manifest.available+main.class">
+ <and>
+ <isset property="manifest.available"/>
+ <isset property="main.class.available"/>
+ </and>
+ </condition>
+ <condition property="do.mkdist">
+ <and>
+ <isset property="libs.CopyLibs.classpath"/>
+ <not>
+ <istrue value="${mkdist.disabled}"/>
+ </not>
+ </and>
+ </condition>
<condition property="manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class}"/>
- <isset property="libs.CopyLibs.classpath"/>
+ <isset property="do.mkdist"/>
</and>
</condition>
+ <condition property="manifest.available+mkdist.available">
+ <and>
+ <istrue value="${manifest.available}"/>
+ <isset property="do.mkdist"/>
+ </and>
+ </condition>
+ <condition property="manifest.available-mkdist.available">
+ <or>
+ <istrue value="${manifest.available}"/>
+ <isset property="do.mkdist"/>
+ </or>
+ </condition>
+ <condition property="manifest.available+main.class-mkdist.available">
+ <or>
+ <istrue value="${manifest.available+main.class}"/>
+ <isset property="do.mkdist"/>
+ </or>
+ </condition>
<condition property="have.tests">
<or>
<available file="${test.src.dir}"/>
@@ -116,6 +160,7 @@ is divided into following sections:
<property name="javadoc.preview" value="true"/>
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
+ <property name="runtime.encoding" value="${source.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
@@ -131,11 +176,9 @@ is divided into following sections:
<condition property="do.depend.true">
<istrue value="${do.depend}"/>
</condition>
- <condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
- <and>
- <isset property="jaxws.endorsed.dir"/>
- <available file="nbproject/jaxws-build.xml"/>
- </and>
+ <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+ <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+ <length length="0" string="${endorsed.classpath}" when="greater"/>
</condition>
</target>
<target name="-post-init">
@@ -171,14 +214,23 @@ is divided into following sections:
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
- <attribute default="/does/not/exist" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="gensrcdir"/>
<element name="customize" optional="true"/>
<sequential>
+ <property location="${build.dir}/empty" name="empty.dir"/>
+ <mkdir dir="${empty.dir}"/>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
+ <src>
+ <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </src>
<classpath>
<path path="@{classpath}"/>
</classpath>
- <compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
+ <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <compilerarg line="${javac.compilerargs}"/>
<customize/>
</javac>
</sequential>
@@ -232,6 +284,7 @@ is divided into following sections:
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg line="${run.jvmargs}"/>
</junit>
</sequential>
@@ -288,8 +341,11 @@ is divided into following sections:
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
@@ -306,12 +362,16 @@ is divided into following sections:
<target name="-init-macrodef-java">
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="classname"/>
+ <attribute default="${run.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
- <path path="${run.classpath}"/>
+ <path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
@@ -335,7 +395,44 @@ is divided into following sections:
COMPILATION SECTION
===================
-->
- <target depends="init" name="deps-jar" unless="no.deps"/>
+ <target name="-deps-jar-init" unless="built-jar.properties">
+ <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+ <delete file="${built-jar.properties}" quiet="true"/>
+ </target>
+ <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-jar.properties}" verbose="false"/>
+ <property file="${built-jar.properties}" prefix="already.built.jar."/>
+ <fail message="Cycle detected: enxio-socket was already built">
+ <condition>
+ <isset property="already.built.jar.${basedir}"/>
+ </condition>
+ </fail>
+ <propertyfile file="${built-jar.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ <antcall target="-maybe-call-dep">
+ <param name="call.built.properties" value="${built-jar.properties}"/>
+ <param location="${project.constantine}" name="call.subproject"/>
+ <param location="${project.constantine}/build.xml" name="call.script"/>
+ <param name="call.target" value="jar"/>
+ <param name="transfer.built-jar.properties" value="${built-jar.properties}"/>
+ </antcall>
+ <antcall target="-maybe-call-dep">
+ <param name="call.built.properties" value="${built-jar.properties}"/>
+ <param location="${project.jaffl}" name="call.subproject"/>
+ <param location="${project.jaffl}/build.xml" name="call.script"/>
+ <param name="call.target" value="jar"/>
+ <param name="transfer.built-jar.properties" value="${built-jar.properties}"/>
+ </antcall>
+ <antcall target="-maybe-call-dep">
+ <param name="call.built.properties" value="${built-jar.properties}"/>
+ <param location="${project.jnr-enxio}" name="call.subproject"/>
+ <param location="${project.jnr-enxio}/build.xml" name="call.script"/>
+ <param name="call.target" value="jar"/>
+ <param name="transfer.built-jar.properties" value="${built-jar.properties}"/>
+ </antcall>
+ </target>
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
<target depends="init" name="-check-automatic-build">
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
@@ -351,10 +448,15 @@ is divided into following sections:
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-depend">
- <j2seproject3:depend/>
+ <pathconvert property="build.generated.subdirs">
+ <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </pathconvert>
+ <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
- <j2seproject3:javac/>
+ <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
@@ -371,7 +473,7 @@ is divided into following sections:
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile/>
- <j2seproject3:javac excludes="" includes="${javac.includes}" sourcepath="${src.dir}"/>
+ <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
</target>
<target name="-post-compile-single">
<!-- Empty placeholder for easier customization. -->
@@ -391,10 +493,10 @@ is divided into following sections:
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
- <target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available-mkdist.available">
<j2seproject1:jar/>
</target>
- <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class-mkdist.available">
<j2seproject1:jar manifest="${manifest.file}"/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
@@ -437,11 +539,53 @@ is divided into following sections:
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+mkdist.available" name="-do-jar-with-libraries-without-mainclass" unless="main.class.available">
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <pathconvert property="run.classpath.without.build.classes.dir">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to=""/>
+ </pathconvert>
+ <pathconvert pathsep=" " property="jar.classpath">
+ <path path="${run.classpath.without.build.classes.dir}"/>
+ <chainedmapper>
+ <flattenmapper/>
+ <globmapper from="*" to="lib/*"/>
+ </chainedmapper>
+ </pathconvert>
+ <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+ <copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+ <fileset dir="${build.classes.dir}"/>
+ <manifest>
+ <attribute name="Class-Path" value="${jar.classpath}"/>
+ </manifest>
+ </copylibs>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.mkdist" name="-do-jar-with-libraries-without-manifest" unless="manifest.available">
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <pathconvert property="run.classpath.without.build.classes.dir">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to=""/>
+ </pathconvert>
+ <pathconvert pathsep=" " property="jar.classpath">
+ <path path="${run.classpath.without.build.classes.dir}"/>
+ <chainedmapper>
+ <flattenmapper/>
+ <globmapper from="*" to="lib/*"/>
+ </chainedmapper>
+ </pathconvert>
+ <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+ <copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+ <fileset dir="${build.classes.dir}"/>
+ <manifest>
+ <attribute name="Class-Path" value="${jar.classpath}"/>
+ </manifest>
+ </copylibs>
+ </target>
<target name="-post-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
- <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
+ <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-mainclass,-do-jar-with-libraries-without-manifest,-post-jar" description="Build JAR." name="jar"/>
<!--
=================
EXECUTION SECTION
@@ -461,6 +605,10 @@ is divided into following sections:
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}"/>
</target>
+ <target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+ </target>
<!--
=================
DEBUGGING SECTION
@@ -469,6 +617,9 @@ is divided into following sections:
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
<j2seproject1:nbjpdastart name="${debug.class}"/>
</target>
+ <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+ <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+ </target>
<target depends="init,compile" name="-debug-start-debuggee">
<j2seproject3:debug>
<customize>
@@ -486,6 +637,11 @@ is divided into following sections:
<j2seproject3:debug classname="${debug.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+ <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+ <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+ <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+ </target>
+ <target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
<target depends="init" name="-pre-debug-fix">
<fail unless="fix.includes">Must set fix.includes</fail>
<property name="javac.includes" value="${fix.includes}.java"/>
@@ -508,6 +664,9 @@ is divided into following sections:
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/*.java"/>
</fileset>
+ <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="**/*.java"/>
+ </fileset>
</javadoc>
</target>
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
@@ -569,7 +728,7 @@ is divided into following sections:
<j2seproject3:junit testincludes="**/*Test.java"/>
</target>
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
- <fail if="tests.failed">Some tests failed; see details above.</fail>
+ <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init" if="have.tests" name="test-report"/>
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
@@ -582,7 +741,7 @@ is divided into following sections:
<j2seproject3:junit excludes="" includes="${test.includes}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
- <fail if="tests.failed">Some tests failed; see details above.</fail>
+ <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
<!--
@@ -648,7 +807,44 @@ is divided into following sections:
CLEANUP SECTION
===============
-->
- <target depends="init" name="deps-clean" unless="no.deps"/>
+ <target name="-deps-clean-init" unless="built-clean.properties">
+ <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+ <delete file="${built-clean.properties}" quiet="true"/>
+ </target>
+ <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-clean.properties}" verbose="false"/>
+ <property file="${built-clean.properties}" prefix="already.built.clean."/>
+ <fail message="Cycle detected: enxio-socket was already built">
+ <condition>
+ <isset property="already.built.clean.${basedir}"/>
+ </condition>
+ </fail>
+ <propertyfile file="${built-clean.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ <antcall target="-maybe-call-dep">
+ <param name="call.built.properties" value="${built-clean.properties}"/>
+ <param location="${project.constantine}" name="call.subproject"/>
+ <param location="${project.constantine}/build.xml" name="call.script"/>
+ <param name="call.target" value="clean"/>
+ <param name="transfer.built-clean.properties" value="${built-clean.properties}"/>
+ </antcall>
+ <antcall target="-maybe-call-dep">
+ <param name="call.built.properties" value="${built-clean.properties}"/>
+ <param location="${project.jaffl}" name="call.subproject"/>
+ <param location="${project.jaffl}/build.xml" name="call.script"/>
+ <param name="call.target" value="clean"/>
+ <param name="transfer.built-clean.properties" value="${built-clean.properties}"/>
+ </antcall>
+ <antcall target="-maybe-call-dep">
+ <param name="call.built.properties" value="${built-clean.properties}"/>
+ <param location="${project.jnr-enxio}" name="call.subproject"/>
+ <param location="${project.jnr-enxio}/build.xml" name="call.script"/>
+ <param name="call.target" value="clean"/>
+ <param name="transfer.built-clean.properties" value="${built-clean.properties}"/>
+ </antcall>
+ </target>
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
@@ -658,4 +854,20 @@ is divided into following sections:
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+ <target name="-check-call-dep">
+ <property file="${call.built.properties}" prefix="already.built."/>
+ <condition property="should.call.dep">
+ <not>
+ <isset property="already.built.${call.subproject}"/>
+ </not>
+ </condition>
+ </target>
+ <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+ <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+ <propertyset>
+ <propertyref prefix="transfer."/>
+ <mapper from="transfer.*" to="*" type="glob"/>
+ </propertyset>
+ </ant>
+ </target>
</project>
View
10 nbproject/genfiles.properties
@@ -1,8 +1,8 @@
-build.xml.data.CRC32=faaf9577
+build.xml.data.CRC32=c0cc878a
build.xml.script.CRC32=ed8d0f13
-build.xml.stylesheet.CRC32=958a1d3e
+build.xml.stylesheet.CRC32=958a1d3e@1.30.1.45
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=faaf9577
-nbproject/build-impl.xml.script.CRC32=86ad6e52
-nbproject/build-impl.xml.stylesheet.CRC32=65b8de21
+nbproject/build-impl.xml.data.CRC32=c0cc878a
+nbproject/build-impl.xml.script.CRC32=a2b465f9
+nbproject/build-impl.xml.stylesheet.CRC32=1022abd3@1.30.1.45
View
22 nbproject/project.properties
@@ -1,8 +1,11 @@
+application.title=enxio-socket
+application.vendor=wayne
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
@@ -17,10 +20,16 @@ debug.test.classpath=\
dist.dir=dist
dist.jar=${dist.dir}/enxio-socket.jar
dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
excludes=
+file.reference.asm-3.2.jar=../jnr~jaffl/lib/asm-3.2.jar
+file.reference.jffi-complete.jar=../jffi-0.6/dist/jffi-complete.jar
includes=**
jar.compress=false
-javac.classpath=
+javac.classpath=\
+ ${reference.constantine.jar}:\
+ ${reference.jaffl.jar}:\
+ ${reference.jnr-enxio.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
@@ -43,10 +52,19 @@ javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
meta.inf.dir=${src.dir}/META-INF
+no.dependencies=true
platform.active=default_platform
+project.constantine=../constantine
+project.jaffl=../jnr~jaffl
+project.jnr-enxio=../enxio
+reference.constantine.jar=${project.constantine}/dist/constantine.jar
+reference.jaffl.jar=${project.jaffl}/dist/jaffl.jar
+reference.jnr-enxio.jar=${project.jnr-enxio}/dist/jnr-enxio.jar
run.classpath=\
${javac.classpath}:\
- ${build.classes.dir}
+ ${build.classes.dir}:\
+ ${file.reference.jffi-complete.jar}:\
+ ${file.reference.asm-3.2.jar}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
View
26 nbproject/project.xml
@@ -15,5 +15,31 @@
<libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
<definitions>./lib/nblibraries.properties</definitions>
</libraries>
+ <references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
+ <reference>
+ <foreign-project>constantine</foreign-project>
+ <artifact-type>jar</artifact-type>
+ <script>build.xml</script>
+ <target>jar</target>
+ <clean-target>clean</clean-target>
+ <id>jar</id>
+ </reference>
+ <reference>
+ <foreign-project>jaffl</foreign-project>
+ <artifact-type>jar</artifact-type>
+ <script>build.xml</script>
+ <target>jar</target>
+ <clean-target>clean</clean-target>
+ <id>jar</id>
+ </reference>
+ <reference>
+ <foreign-project>jnr-enxio</foreign-project>
+ <artifact-type>jar</artifact-type>
+ <script>build.xml</script>
+ <target>jar</target>
+ <clean-target>clean</clean-target>
+ <id>jar</id>
+ </reference>
+ </references>
</configuration>
</project>
View
85 src/com/kenai/jnr/unixsocket/Native.java
@@ -0,0 +1,85 @@
+
+package com.kenai.jnr.unixsocket;
+
+import com.kenai.constantine.platform.ProtocolFamily;
+import com.kenai.constantine.platform.Sock;
+import com.kenai.jaffl.LastError;
+import com.kenai.jaffl.Library;
+import com.kenai.jaffl.Platform;
+import com.kenai.jaffl.annotations.In;
+import com.kenai.jaffl.annotations.Out;
+import com.kenai.jaffl.annotations.Transient;
+import com.kenai.jaffl.byref.IntByReference;
+import java.io.IOException;
+
+class Native {
+ static final String[] libnames = Platform.getPlatform().getOS() == Platform.OS.SOLARIS
+ ? new String[] { "socket", "nsl", "c" }
+ : new String[] { "c" };
+ public static interface LibC {
+ static final LibC INSTANCE = Library.loadLibrary(LibC.class, libnames);
+ public static final int F_GETFL = com.kenai.constantine.platform.Fcntl.F_GETFL.value();
+ public static final int F_SETFL = com.kenai.constantine.platform.Fcntl.F_SETFL.value();
+ public static final int O_NONBLOCK = com.kenai.constantine.platform.OpenFlags.O_NONBLOCK.value();
+
+ int socket(int domain, int type, int protocol);
+ int listen(int fd, int backlog);
+ int bind(int fd, @In @Out @Transient SockAddrUnix addr, int len);
+ int accept(int fd, @Out SockAddrUnix addr, @In @Out IntByReference len);
+ int connect(int s, @In @Transient SockAddrUnix name, int namelen);
+ int getsockname(int fd, @Out SockAddrUnix addr, @In @Out IntByReference len);
+ int getpeername(int fd, @Out SockAddrUnix addr, @In @Out IntByReference len);
+ int fcntl(int fd, int cmd, int data);
+ String strerror(int error);
+ }
+
+ static final LibC libsocket() {
+ return LibC.INSTANCE;
+ }
+
+ static final LibC libc() {
+ return LibC.INSTANCE;
+ }
+
+ static int socket(ProtocolFamily domain, Sock type, int protocol) throws IOException {
+ int fd = libsocket().socket(domain.value(), type.value(), protocol);
+ if (fd < 0) {
+ throw new IOException(getLastErrorString());
+ }
+ return fd;
+ }
+
+ static int listen(int fd, int backlog) {
+ return libsocket().listen(fd, backlog);
+ }
+
+ static int bind(int fd, SockAddrUnix addr, int len) {
+ return libsocket().bind(fd, addr, len);
+ }
+
+ static int accept(int fd, SockAddrUnix addr, IntByReference len) {
+ return libsocket().accept(fd, addr, len);
+ }
+
+ static int connect(int fd, SockAddrUnix addr, int len) {
+ return libsocket().connect(fd, addr, len);
+ }
+
+ static String getLastErrorString() {
+ return strerror(LastError.getLastError());
+ }
+
+ static String strerror(int error) {
+ return libc().strerror(error);
+ }
+
+ public static void setBlocking(int fd, boolean block) {
+ int flags = libc().fcntl(fd, LibC.F_GETFL, 0);
+ if (block) {
+ flags &= ~LibC.O_NONBLOCK;
+ } else {
+ flags |= LibC.O_NONBLOCK;
+ }
+ libc().fcntl(fd, LibC.F_SETFL, flags);
+ }
+}
View
122 src/com/kenai/jnr/unixsocket/SockAddrUnix.java
@@ -0,0 +1,122 @@
+package com.kenai.jnr.unixsocket;
+
+import com.kenai.constantine.platform.ProtocolFamily;
+import com.kenai.jaffl.Platform;
+import com.kenai.jaffl.struct.Struct;
+import com.kenai.jaffl.struct.Struct.UTF8String;
+import com.kenai.jaffl.struct.Struct.Unsigned16;
+import com.kenai.jaffl.struct.Struct.Unsigned8;
+
+/**
+ * Native unix domain socket address structure.
+ */
+abstract class SockAddrUnix extends Struct {
+ public final static int ADDR_LENGTH = 108;
+
+ protected abstract UTF8String getPathField();
+ protected abstract NumberField getFamilyField();
+
+ /**
+ * Sets the protocol family of this unix socket address.
+ *
+ * @param family The protocol family, usually {@link com.kenai.constantine.platform.ProtocolFamily.PF_UNIX}
+ */
+ public final void setFamily(ProtocolFamily family) {
+ getFamilyField().set(family.value());
+ }
+
+
+ /**
+ * Gets the protocol family of this unix socket address.
+ *
+ * @return The protocol family
+ */
+ public final ProtocolFamily getFamily() {
+ return ProtocolFamily.valueOf(getFamilyField().intValue());
+ }
+
+ /**
+ * Sets the file system path of this socket address
+ *
+ * @param path The unix socket address
+ */
+ public final void setPath(java.lang.String path) {
+ getPathField().set(path);
+ }
+
+ /**
+ * Gets the file system path of this socket address
+ *
+ * @return A String
+ */
+ public final java.lang.String getPath() {
+ return getPathField().get();
+ }
+
+ /**
+ * Gets the maximum length of this address (including len/family header)
+ *
+ * @return The maximum size of the address in bytes
+ */
+ public int getMaximumLength() {
+ return 2 + getPathField().length();
+ }
+
+ /**
+ * Gets the actual length of this address (including len/family header)
+ *
+ * @return The actual size of this address, in bytes
+ */
+ public int length() {
+ return 2 + strlen(getPathField());
+ }
+
+
+ /**
+ * Creates a new instance of <tt>SockAddrUnix</tt>
+ *
+ * @return An instance of <tt>SockAddrUnix</tt>
+ */
+ static SockAddrUnix create() {
+ return Platform.getPlatform().isBSD() ? new BSDSockAddrUnix() : new DefaultSockAddrUnix();
+ }
+
+ private static final int strlen(UTF8String str) {
+ int end = str.getMemoryIO().indexOf(str.offset(), (byte) 0);
+ return end >= 0 ? end : str.length();
+ }
+
+ /**
+ * An implementation of {@link SockAddrUnix} for BSD systems
+ */
+ static final class BSDSockAddrUnix extends SockAddrUnix {
+
+ public final Unsigned8 sun_len = new Unsigned8();
+ public final Unsigned8 sun_family = new Unsigned8();
+ public final UTF8String sun_addr = new UTF8String(ADDR_LENGTH);
+
+ protected final UTF8String getPathField() {
+ return sun_addr;
+ }
+ protected final NumberField getFamilyField() {
+ return sun_family;
+ }
+ }
+
+
+ /**
+ * An implementation of {@link SockAddrUnix} for Linux, Solaris, et, al
+ */
+ static final class DefaultSockAddrUnix extends SockAddrUnix {
+ public final Unsigned16 sun_family = new Unsigned16();
+ public final UTF8String sun_addr = new UTF8String(ADDR_LENGTH);
+
+ protected final UTF8String getPathField() {
+ return sun_addr;
+ }
+
+ protected final NumberField getFamilyField() {
+ return sun_family;
+ }
+ }
+}
View
44 src/com/kenai/jnr/unixsocket/UnixServerSocket.java
@@ -0,0 +1,44 @@
+
+package com.kenai.jnr.unixsocket;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+
+public class UnixServerSocket {
+ final UnixServerSocketChannel channel;
+ final int fd;
+
+ public UnixServerSocket() throws IOException {
+ this.channel = new UnixServerSocketChannel(this);
+ this.fd = channel.getFD();
+ }
+
+ UnixServerSocket(UnixServerSocketChannel channel) {
+ this.channel = channel;
+ this.fd = channel.getFD();
+ }
+
+ public UnixSocket accept() throws IOException {
+ return new UnixSocket(channel.accept());
+ }
+
+ public void bind(SocketAddress endpoint) throws java.io.IOException {
+ bind(endpoint, 128);
+ }
+
+ public void bind(SocketAddress endpoint, int backlog) throws java.io.IOException {
+ if (!(endpoint instanceof UnixSocketAddress)) {
+ throw new IOException("Invalid address");
+ }
+ UnixSocketAddress addr = (UnixSocketAddress) endpoint;
+
+ if (Native.bind(fd, addr.getStruct(), addr.length()) < 0) {
+ throw new IOException("bind failed: " + Native.getLastErrorString());
+ }
+
+ if (Native.listen(fd, backlog) < 0) {
+ throw new IOException("listen failed: " + Native.getLastErrorString());
+ }
+ }
+
+}
View
53 src/com/kenai/jnr/unixsocket/UnixServerSocketChannel.java
@@ -0,0 +1,53 @@
+
+package com.kenai.jnr.unixsocket;
+
+import com.kenai.constantine.platform.ProtocolFamily;
+import com.kenai.constantine.platform.Sock;
+import com.kenai.jaffl.byref.IntByReference;
+import com.kenai.jnr.enxio.channels.NativeServerSocketChannel;
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ *
+ */
+public class UnixServerSocketChannel extends NativeServerSocketChannel {
+
+ private final UnixServerSocket socket;
+
+ UnixServerSocketChannel(UnixServerSocket socket) throws IOException {
+ super(Native.socket(ProtocolFamily.PF_UNIX, Sock.SOCK_STREAM, 0));
+ this.socket = new UnixServerSocket(this);
+ }
+
+ UnixServerSocketChannel(SelectorProvider provider, int fd) {
+ super(provider, fd, SelectionKey.OP_ACCEPT);
+ this.socket = new UnixServerSocket(this);
+ }
+
+ public static UnixServerSocketChannel open() throws IOException {
+ return new UnixServerSocket().channel;
+ }
+
+ public UnixSocketChannel accept() throws IOException {
+ UnixSocketAddress remote = new UnixSocketAddress();
+ SockAddrUnix addr = remote.getStruct();
+ IntByReference len = new IntByReference(addr.getMaximumLength());
+
+ int clientfd = Native.accept(getFD(), addr, len);
+
+ if (clientfd < 0) {
+ throw new IOException("accept failed: " + Native.getLastErrorString());
+ }
+
+ // Always force the socket back to blocking mode
+ Native.setBlocking(clientfd, true);
+
+ return new UnixSocketChannel(clientfd, remote);
+ }
+
+ public final UnixServerSocket socket() {
+ return socket;
+ }
+}
View
17 src/com/kenai/jnr/unixsocket/UnixSocket.java
@@ -0,0 +1,17 @@
+
+package com.kenai.jnr.unixsocket;
+
+import com.kenai.jnr.enxio.channels.NativeSocketChannel;
+import java.nio.channels.Channel;
+
+public class UnixSocket {
+ private final NativeSocketChannel channel;
+
+ UnixSocket(NativeSocketChannel channel) {
+ this.channel = channel;
+ }
+
+ public final Channel getChannel() {
+ return channel;
+ }
+}
View
32 src/com/kenai/jnr/unixsocket/UnixSocketAddress.java
@@ -0,0 +1,32 @@
+
+package com.kenai.jnr.unixsocket;
+
+import com.kenai.constantine.platform.ProtocolFamily;
+
+public class UnixSocketAddress extends java.net.SocketAddress {
+ private final SockAddrUnix address;
+
+ UnixSocketAddress() {
+ address = SockAddrUnix.create();
+ address.setFamily(ProtocolFamily.PF_UNIX);
+ }
+
+ public UnixSocketAddress(java.io.File path) {
+ address = SockAddrUnix.create();
+ address.setFamily(ProtocolFamily.PF_UNIX);
+ address.setPath(path.getAbsolutePath());
+ }
+
+ SockAddrUnix getStruct() {
+ return address;
+ }
+
+ int length() {
+ return address.length();
+ }
+
+ @Override
+ public String toString() {
+ return "[family=" + address.getFamily() + " path=" + address.getPath() + "]";
+ }
+}
View
146 src/com/kenai/jnr/unixsocket/UnixSocketChannel.java
@@ -0,0 +1,146 @@
+
+package com.kenai.jnr.unixsocket;
+
+import com.kenai.constantine.platform.Errno;
+import com.kenai.constantine.platform.ProtocolFamily;
+import com.kenai.constantine.platform.Sock;
+import com.kenai.jaffl.LastError;
+import com.kenai.jaffl.byref.IntByReference;
+import com.kenai.jnr.enxio.channels.NativeSocketChannel;
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+
+/**
+ * A {@link java.nio.channels.Channel} implementation that uses a native unix socket
+ */
+public class UnixSocketChannel extends NativeSocketChannel {
+ static enum State {
+ UNINITIALIZED,
+ CONNECTED,
+ IDLE,
+ CONNECTING,
+ }
+ private volatile State state;
+ private UnixSocketAddress remoteAddress = null;
+ private UnixSocketAddress localAddress = null;
+ private final Object stateLock = new Object();
+
+ public static final UnixSocketChannel open() throws IOException {
+ return new UnixSocketChannel();
+ }
+
+ public static final UnixSocketChannel open(UnixSocketAddress remote) throws IOException {
+ UnixSocketChannel channel = new UnixSocketChannel();
+ channel.connect(remote);
+ return channel;
+ }
+
+ private UnixSocketChannel() throws IOException {
+ super(Native.socket(ProtocolFamily.PF_UNIX, Sock.SOCK_STREAM, 0),
+ SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
+ state = State.IDLE;
+ }
+
+ UnixSocketChannel(int fd, int ops) {
+ super(fd, ops);
+ state = State.CONNECTED;
+ }
+
+ UnixSocketChannel(int fd, UnixSocketAddress remote) {
+ super(fd, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
+ state = State.CONNECTED;
+ remoteAddress = remote;
+ }
+
+ private final boolean doConnect(SockAddrUnix remote) throws IOException {
+ if (Native.connect(getFD(), remote, remote.length()) != 0) {
+ Errno error = Errno.valueOf(LastError.getLastError());
+
+ switch (error) {
+ case EAGAIN:
+ case EWOULDBLOCK:
+ return false;
+
+ default:
+ throw new IOException(error.toString());
+ }
+ }
+ return true;
+ }
+
+ public boolean connect(UnixSocketAddress remote) throws IOException {
+ remoteAddress = remote;
+ if (!doConnect(remoteAddress.getStruct())) {
+
+ state = State.CONNECTING;
+ return false;
+
+ } else {
+
+ state = State.CONNECTED;
+ return true;
+ }
+ }
+
+ public boolean isConnected() {
+ return state == State.CONNECTED;
+ }
+
+ public boolean isConnectionPending() {
+ return state == State.CONNECTING;
+ }
+
+ public boolean finishConnect() throws IOException {
+ switch (state) {
+ case CONNECTED:
+ return true;
+
+ case CONNECTING:
+ if (!doConnect(remoteAddress.getStruct())) {
+ return false;
+ }
+ state = State.CONNECTED;
+ return true;
+
+ default:
+ throw new IllegalStateException("socket is not waiting for connect to complete");
+ }
+ }
+
+ public final UnixSocketAddress getRemoteSocketAddress() {
+ if (state != State.CONNECTED) {
+ return null;
+ }
+ return remoteAddress != null ? remoteAddress : (remoteAddress = getpeername(getFD()));
+ }
+
+ public final UnixSocketAddress getLocalSocketAddress() {
+ if (state != State.CONNECTED) {
+ return null;
+ }
+
+ return localAddress != null ? localAddress : (localAddress = getsockname(getFD()));
+ }
+
+ static UnixSocketAddress getpeername(int sockfd) {
+ UnixSocketAddress remote = new UnixSocketAddress();
+ IntByReference len = new IntByReference(remote.getStruct().getMaximumLength());
+
+ if (Native.libc().getpeername(sockfd, remote.getStruct(), len) < 0) {
+ throw new Error(Native.getLastErrorString());
+ }
+
+ return remote;
+ }
+
+ static UnixSocketAddress getsockname(int sockfd) {
+ UnixSocketAddress remote = new UnixSocketAddress();
+ IntByReference len = new IntByReference(remote.getStruct().getMaximumLength());
+
+ if (Native.libc().getsockname(sockfd, remote.getStruct(), len) < 0) {
+ throw new Error(Native.getLastErrorString());
+ }
+
+ return remote;
+ }
+}
View
34 src/example/UnixClient.java
@@ -0,0 +1,34 @@
+
+package example;
+
+import com.kenai.jnr.unixsocket.UnixSocketAddress;
+import com.kenai.jnr.unixsocket.UnixSocketChannel;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.nio.CharBuffer;
+import java.nio.channels.Channels;
+
+public class UnixClient {
+ public static final void main(String[] args) throws IOException {
+ java.io.File path = new java.io.File("/tmp/fubar.sock");
+ String data = "blah blah";
+ UnixSocketAddress address = new UnixSocketAddress(path);
+ UnixSocketChannel channel = UnixSocketChannel.open(address);
+ System.out.println("connected to " + channel.getRemoteSocketAddress());
+ PrintWriter w = new PrintWriter(Channels.newOutputStream(channel));
+ w.print(data);
+ w.flush();
+
+ InputStreamReader r = new InputStreamReader(Channels.newInputStream(channel));
+ CharBuffer result = CharBuffer.allocate(1024);
+ r.read(result);
+ result.flip();
+ System.out.println("read from server: " + result.toString());
+ if (!result.toString().equals(data)) {
+ System.out.println("ERROR: data mismatch");
+ } else {
+ System.out.println("SUCCESS");
+ }
+ }
+}
View
98 src/example/UnixServer.java
@@ -0,0 +1,98 @@
+
+package example;
+
+import com.kenai.jnr.unixsocket.UnixServerSocket;
+import com.kenai.jnr.unixsocket.UnixServerSocketChannel;
+import com.kenai.jnr.unixsocket.UnixSocketAddress;
+import com.kenai.jnr.unixsocket.UnixSocketChannel;
+import com.kenai.jnr.enxio.channels.NativeSelectorProvider;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class UnixServer {
+
+ public static void main(String[] args) throws IOException {
+ java.io.File path = new java.io.File("/tmp/fubar.sock");
+ path.deleteOnExit();
+ UnixSocketAddress address = new UnixSocketAddress(path);
+ UnixServerSocketChannel channel = UnixServerSocketChannel.open();
+
+ try {
+ Selector sel = NativeSelectorProvider.getInstance().openSelector();
+ channel.configureBlocking(false);
+ channel.socket().bind(address);
+ channel.register(sel, SelectionKey.OP_ACCEPT, new ServerActor(channel, sel));
+
+ while (sel.select() > 0) {
+ Set<SelectionKey> keys = sel.selectedKeys();
+ for (SelectionKey k : keys) {
+ Actor a = (Actor) k.attachment();
+ if (!a.rxready()) {
+ k.cancel();
+ }
+ }
+ }
+ } catch (IOException ex) {
+ Logger.getLogger(UnixServerSocket.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+
+ static interface Actor {
+ public boolean rxready();
+ }
+
+ static final class ServerActor implements Actor {
+ private final UnixServerSocketChannel channel;
+ private final Selector selector;
+
+ public ServerActor(UnixServerSocketChannel channel, Selector selector) {
+ this.channel = channel;
+ this.selector = selector;
+ }
+ public final boolean rxready() {
+ try {
+ UnixSocketChannel client = channel.accept();
+ client.configureBlocking(false);
+ client.register(selector, SelectionKey.OP_READ, new ClientActor(client));
+ return true;
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+ }
+ static final class ClientActor implements Actor {
+ private final UnixSocketChannel channel;
+
+ public ClientActor(UnixSocketChannel channel) {
+ this.channel = channel;
+ }
+
+ public final boolean rxready() {
+ try {
+ ByteBuffer buf = ByteBuffer.allocate(1024);
+ int n = channel.read(buf);
+ UnixSocketAddress remote = channel.getRemoteSocketAddress();
+ System.out.printf("Read in %d bytes from %s\n", n, remote);
+
+ if (n > 0) {
+ buf.flip();
+ channel.write(buf);
+ return true;
+ } else if (n < 0) {
+ return false;
+ }
+
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.