Added jtux C files
diff --git a/JNI_macros.h b/JNI_macros.h
new file mode 100755
index 0000000..29795fd
--- /dev/null
+++ b/JNI_macros.h
@@ -0,0 +1,35 @@
+#define JSTR_GET_DECL(s_c, s)\
+	const char *s_c = (*env)->GetStringUTFChars(env, s, NULL);
+
+#define JTHROW_neg1(e)\
+	if ((intptr_t)(e) == (intptr_t)-1)\
+		(void)setup_throw_errno(env, errno);
+
+#define JTHROW_null(e)\
+	if ((e) == NULL)\
+		(void)setup_throw_errno(env, errno);
+
+#define JTHROW_nzero(e)\
+	if ((e) != 0)\
+		(void)setup_throw_errno(env, errno);
+
+#define JTHROW_rv(e)\
+	{\
+		int JTHROW_rv_r;\
+		if ((JTHROW_rv_r = (e)) > 0)\
+			(void)setup_throw_errno(env, JTHROW_rv_r);\
+	}
+
+#define JSTR_REL(s_c, s)\
+	(*env)->ReleaseStringUTFChars(env, s, s_c);
+
+#define JSTR_NULLTEST(s_c)\
+	if (s_c == NULL)\
+		return;
+
+#define JSTR_NULLTEST_V(s_c, v)\
+	if (s_c == NULL)\
+		return v;
+
+#define JSTR_RETURN(r)\
+	return (*env)->NewStringUTF(env, r);
diff --git a/JtuxClock.h b/JtuxClock.h
new file mode 100755
index 0000000..b178612
--- /dev/null
+++ b/JtuxClock.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UClock */
+
+#ifndef _Included_jtux_UClock
+#define _Included_jtux_UClock
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UClock
+ * Method:    alarm
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UClock_alarm
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UClock
+ * Method:    nanosleep
+ * Signature: (Ljtux/UProcess$s_timespec;Ljtux/UProcess$s_timespec;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UClock_nanosleep
+  (JNIEnv *, jclass, jobject, jobject);
+
+/*
+ * Class:     jtux_UClock
+ * Method:    sleep
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UClock_sleep
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UClock
+ * Method:    usleep
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UClock_usleep
+  (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxDir.h b/JtuxDir.h
new file mode 100755
index 0000000..6145e68
--- /dev/null
+++ b/JtuxDir.h
@@ -0,0 +1,77 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UDir */
+
+#ifndef _Included_jtux_UDir
+#define _Included_jtux_UDir
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UDir
+ * Method:    closedir
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UDir_closedir
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UDir
+ * Method:    mkdir
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UDir_mkdir
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_UDir
+ * Method:    opendir
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UDir_opendir
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UDir
+ * Method:    readdir
+ * Signature: (J)Ljtux/UDir$s_dirent;
+ */
+JNIEXPORT jobject JNICALL Java_jtux_UDir_readdir
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UDir
+ * Method:    rewinddir
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UDir_rewinddir
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UDir
+ * Method:    rmdir
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UDir_rmdir
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UDir
+ * Method:    seekdir
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UDir_seekdir
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     jtux_UDir
+ * Method:    telldir
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UDir_telldir
+  (JNIEnv *, jclass, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxFile$fd_set.h b/JtuxFile$fd_set.h
new file mode 100755
index 0000000..a2c4096
--- /dev/null
+++ b/JtuxFile$fd_set.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UFile_fd_0005fset */
+
+#ifndef _Included_jtux_UFile_fd_0005fset
+#define _Included_jtux_UFile_fd_0005fset
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UFile_fd_0005fset
+ * Method:    GetSize_fd_set
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_00024fd_1set_GetSize_1fd_1set
+  (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxFile.h b/JtuxFile.h
new file mode 100755
index 0000000..05b2f5c
--- /dev/null
+++ b/JtuxFile.h
@@ -0,0 +1,453 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UFile */
+
+#ifndef _Included_jtux_UFile
+#define _Included_jtux_UFile
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UFile
+ * Method:    access
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_access
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    chmod
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_chmod
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    chown
+ * Signature: (Ljava/lang/String;JJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_chown
+  (JNIEnv *, jclass, jstring, jlong, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    close
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_close
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    dup
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_dup
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    dup2
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_dup2
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    fchmod
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_fchmod
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    fchown
+ * Signature: (IJJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_fchown
+  (JNIEnv *, jclass, jint, jlong, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    fcntl
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_fcntl
+  (JNIEnv *, jclass, jint, jint, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    FD_ZERO
+ * Signature: (Ljtux/UFile$fd_set;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_FD_1ZERO
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    FD_SET
+ * Signature: (ILjtux/UFile$fd_set;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_FD_1SET
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    FD_CLR
+ * Signature: (ILjtux/UFile$fd_set;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_FD_1CLR
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    FD_ISSET
+ * Signature: (ILjtux/UFile$fd_set;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_FD_1ISSET
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    fdatasync
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_fdatasync
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    fstat
+ * Signature: (ILjtux/UFile$s_stat;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_fstat
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    fstatvfs
+ * Signature: (ILjtux/UFile$s_statvfs;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_fstatvfs
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    fsync
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_fsync
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    ftruncate
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_ftruncate
+  (JNIEnv *, jclass, jint, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    lchown
+ * Signature: (Ljava/lang/String;JJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_lchown
+  (JNIEnv *, jclass, jstring, jlong, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    link
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_link
+  (JNIEnv *, jclass, jstring, jstring);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    lockf
+ * Signature: (IIJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_lockf
+  (JNIEnv *, jclass, jint, jint, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    lseek
+ * Signature: (IJI)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UFile_lseek
+  (JNIEnv *, jclass, jint, jlong, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    lstat
+ * Signature: (Ljava/lang/String;Ljtux/UFile$s_stat;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_lstat
+  (JNIEnv *, jclass, jstring, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    mkfifo
+ * Signature: (Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_mkfifo
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    mknod
+ * Signature: (Ljava/lang/String;II)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_mknod
+  (JNIEnv *, jclass, jstring, jint, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    mkstemp
+ * Signature: (Ljava/lang/StringBuffer;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_mkstemp
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    open
+ * Signature: (Ljava/lang/String;II)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_open
+  (JNIEnv *, jclass, jstring, jint, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    pipe
+ * Signature: ([I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_pipe
+  (JNIEnv *, jclass, jintArray);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    poll
+ * Signature: ([Ljtux/UFile$s_pollfd;II)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_poll
+  (JNIEnv *, jclass, jobjectArray, jint, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    pread
+ * Signature: (I[BIJ)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_pread
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    pselect
+ * Signature: (ILjtux/UFile$fd_set;Ljtux/UFile$fd_set;Ljtux/UFile$fd_set;Ljtux/UProcess$s_timespec;Ljtux/UProcess$sigset_t;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_pselect
+  (JNIEnv *, jclass, jint, jobject, jobject, jobject, jobject, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    pwrite
+ * Signature: (I[BIJ)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_pwrite
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    read
+ * Signature: (I[BI)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_read
+  (JNIEnv *, jclass, jint, jbyteArray, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    readlink
+ * Signature: (Ljava/lang/String;[BI)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_readlink
+  (JNIEnv *, jclass, jstring, jbyteArray, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    readv
+ * Signature: (I[Ljtux/UFile$s_iovec;I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_readv
+  (JNIEnv *, jclass, jint, jobjectArray, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    rename
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_rename
+  (JNIEnv *, jclass, jstring, jstring);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    S_ISBLK
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISBLK
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    S_ISCHR
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISCHR
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    S_ISDIR
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISDIR
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    S_ISFIFO
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISFIFO
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    S_ISLNK
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISLNK
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    S_ISREG
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISREG
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    S_ISSOCK
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISSOCK
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    select
+ * Signature: (ILjtux/UFile$fd_set;Ljtux/UFile$fd_set;Ljtux/UFile$fd_set;Ljtux/UProcess$s_timeval;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_select
+  (JNIEnv *, jclass, jint, jobject, jobject, jobject, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    stat
+ * Signature: (Ljava/lang/String;Ljtux/UFile$s_stat;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_stat
+  (JNIEnv *, jclass, jstring, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    statvfs
+ * Signature: (Ljava/lang/String;Ljtux/UFile$s_statvfs;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_statvfs
+  (JNIEnv *, jclass, jstring, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    symlink
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_symlink
+  (JNIEnv *, jclass, jstring, jstring);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    sync
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_sync
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    truncate
+ * Signature: (Ljava/lang/String;J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_truncate
+  (JNIEnv *, jclass, jstring, jlong);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    unlink
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_unlink
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    utime
+ * Signature: (Ljava/lang/String;Ljtux/UFile$s_utimbuf;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UFile_utime
+  (JNIEnv *, jclass, jstring, jobject);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    write
+ * Signature: (I[BI)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_write
+  (JNIEnv *, jclass, jint, jbyteArray, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    ioctl
+ * Signature: (II[B)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_ioctl
+  (JNIEnv *, jclass, jint, jint, jbyteArray);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    ioctl2
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_ioctl2
+  (JNIEnv *, jclass, jint, jint, jint);
+
+/*
+ * Class:     jtux_UFile
+ * Method:    writev
+ * Signature: (I[Ljtux/UFile$s_iovec;I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UFile_writev
+  (JNIEnv *, jclass, jint, jobjectArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxNetwork.h b/JtuxNetwork.h
new file mode 100755
index 0000000..d6a341c
--- /dev/null
+++ b/JtuxNetwork.h
@@ -0,0 +1,237 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UNetwork */
+
+#ifndef _Included_jtux_UNetwork
+#define _Included_jtux_UNetwork
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UNetwork
+ * Method:    accept
+ * Signature: (ILjtux/UNetwork$s_sockaddr;Ljtux/UUtil$IntHolder;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_accept
+  (JNIEnv *, jclass, jint, jobject, jobject);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    bind
+ * Signature: (ILjtux/UNetwork$s_sockaddr;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_bind
+  (JNIEnv *, jclass, jint, jobject, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    connect
+ * Signature: (ILjtux/UNetwork$s_sockaddr;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_connect
+  (JNIEnv *, jclass, jint, jobject, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    freeaddrinfo
+ * Signature: (Ljtux/UNetwork$s_addrinfo;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_freeaddrinfo
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    gai_strerror
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jtux_UNetwork_gai_1strerror
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    getaddrinfo
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Ljtux/UNetwork$s_addrinfo;Ljtux/UNetwork$AddrInfoListHead;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_getaddrinfo
+  (JNIEnv *, jclass, jstring, jstring, jobject, jobject);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    gethostid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UNetwork_gethostid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    gethostname
+ * Signature: (Ljava/lang/StringBuffer;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_gethostname
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    getnameinfo
+ * Signature: (Ljtux/UNetwork$s_sockaddr;ILjava/lang/StringBuffer;Ljava/lang/StringBuffer;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_getnameinfo
+  (JNIEnv *, jclass, jobject, jint, jobject, jobject, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    getsockopt
+ * Signature: (IIILjtux/UNetwork$SockOptValue;Ljtux/UUtil$IntHolder;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_getsockopt
+  (JNIEnv *, jclass, jint, jint, jint, jobject, jobject);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    htonl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_htonl
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    htons
+ * Signature: (S)S
+ */
+JNIEXPORT jshort JNICALL Java_jtux_UNetwork_htons
+  (JNIEnv *, jclass, jshort);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    inet_ntop
+ * Signature: (II)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jtux_UNetwork_inet_1ntop__II
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    inet_ntop
+ * Signature: (I[B)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jtux_UNetwork_inet_1ntop__I_3B
+  (JNIEnv *, jclass, jint, jbyteArray);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    inet_pton
+ * Signature: (ILjava/lang/String;Ljtux/UUtil$IntHolder;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_inet_1pton__ILjava_lang_String_2Ljtux_UUtil_00024IntHolder_2
+  (JNIEnv *, jclass, jint, jstring, jobject);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    inet_pton
+ * Signature: (ILjava/lang/String;[B)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_inet_1pton__ILjava_lang_String_2_3B
+  (JNIEnv *, jclass, jint, jstring, jbyteArray);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    listen
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_listen
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    ntohl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_ntohl
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    ntohs
+ * Signature: (S)S
+ */
+JNIEXPORT jshort JNICALL Java_jtux_UNetwork_ntohs
+  (JNIEnv *, jclass, jshort);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    recv
+ * Signature: (I[BII)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_recv
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    recvfrom
+ * Signature: (I[BIILjtux/UNetwork$s_sockaddr;Ljtux/UUtil$IntHolder;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_recvfrom
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jint, jobject, jobject);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    recvmsg
+ * Signature: (ILjtux/UNetwork$s_msghdr;I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_recvmsg
+  (JNIEnv *, jclass, jint, jobject, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    send
+ * Signature: (I[BII)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_send
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    sendmsg
+ * Signature: (ILjtux/UNetwork$s_msghdr;I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_sendmsg
+  (JNIEnv *, jclass, jint, jobject, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    sendto
+ * Signature: (I[BIILjtux/UNetwork$s_sockaddr;I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_sendto
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jint, jobject, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    setsockopt
+ * Signature: (IIILjtux/UNetwork$SockOptValue;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UNetwork_setsockopt
+  (JNIEnv *, jclass, jint, jint, jint, jobject, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    sockatmark
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_sockatmark
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UNetwork
+ * Method:    socket
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_socket
+  (JNIEnv *, jclass, jint, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxPosixIPC.h b/JtuxPosixIPC.h
new file mode 100755
index 0000000..a242a96
--- /dev/null
+++ b/JtuxPosixIPC.h
@@ -0,0 +1,221 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UPosixIPC */
+
+#ifndef _Included_jtux_UPosixIPC
+#define _Included_jtux_UPosixIPC
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mmap
+ * Signature: (JIIIIJ)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_mmap
+  (JNIEnv *, jclass, jlong, jint, jint, jint, jint, jlong);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_close
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1close
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_getattr
+ * Signature: (JLjtux/UPosixIPC$s_mq_attr;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1getattr
+  (JNIEnv *, jclass, jlong, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_notify
+ * Signature: (JLjtux/UProcess$s_sigevent;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1notify
+  (JNIEnv *, jclass, jlong, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_open
+ * Signature: (Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_mq_1open__Ljava_lang_String_2I
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_open
+ * Signature: (Ljava/lang/String;IILjtux/UPosixIPC$s_mq_attr;)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_mq_1open__Ljava_lang_String_2IILjtux_UPosixIPC_00024s_1mq_1attr_2
+  (JNIEnv *, jclass, jstring, jint, jint, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_receive
+ * Signature: (J[BILjtux/UUtil$IntHolder;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UPosixIPC_mq_1receive
+  (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_send
+ * Signature: (J[BII)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1send
+  (JNIEnv *, jclass, jlong, jbyteArray, jint, jint);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_setattr
+ * Signature: (JLjtux/UPosixIPC$s_mq_attr;Ljtux/UPosixIPC$s_mq_attr;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1setattr
+  (JNIEnv *, jclass, jlong, jobject, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_timedreceive
+ * Signature: (J[BILjtux/UUtil$IntHolder;Ljtux/UProcess$s_timespec;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UPosixIPC_mq_1timedreceive
+  (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_timedsend
+ * Signature: (J[BIILjtux/UProcess$s_timespec;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1timedsend
+  (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    mq_unlink
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1unlink
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    munmap
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_munmap
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_close
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1close
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_destroy
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1destroy
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_getvalue
+ * Signature: (JLjtux/UUtil$IntHolder;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1getvalue
+  (JNIEnv *, jclass, jlong, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_init
+ * Signature: (JII)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1init
+  (JNIEnv *, jclass, jlong, jint, jint);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_open
+ * Signature: (Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_sem_1open__Ljava_lang_String_2I
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_open
+ * Signature: (Ljava/lang/String;III)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_sem_1open__Ljava_lang_String_2III
+  (JNIEnv *, jclass, jstring, jint, jint, jint);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_post
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1post
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_timedwait
+ * Signature: (JLjtux/UProcess$s_timespec;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1timedwait
+  (JNIEnv *, jclass, jlong, jobject);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_trywait
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1trywait
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_unlink
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1unlink
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    sem_wait
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1wait
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    shm_open
+ * Signature: (Ljava/lang/String;II)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UPosixIPC_shm_1open
+  (JNIEnv *, jclass, jstring, jint, jint);
+
+/*
+ * Class:     jtux_UPosixIPC
+ * Method:    shm_unlink
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_shm_1unlink
+  (JNIEnv *, jclass, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxProcess$sigset_t.h b/JtuxProcess$sigset_t.h
new file mode 100755
index 0000000..5945aca
--- /dev/null
+++ b/JtuxProcess$sigset_t.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UProcess_sigset_0005ft */
+
+#ifndef _Included_jtux_UProcess_sigset_0005ft
+#define _Included_jtux_UProcess_sigset_0005ft
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UProcess_sigset_0005ft
+ * Method:    GetSize_sigset_t
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UProcess_00024sigset_1t_GetSize_1sigset_1t
+  (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxProcess.h b/JtuxProcess.h
new file mode 100755
index 0000000..bce78b6
--- /dev/null
+++ b/JtuxProcess.h
@@ -0,0 +1,462 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UProcess */
+
+#ifndef _Included_jtux_UProcess
+#define _Included_jtux_UProcess
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Inaccessible static: signalHandlers */
+/*
+ * Class:     jtux_UProcess
+ * Method:    abort
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_abort
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    chdir
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_chdir
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    chroot
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_chroot
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    clock
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_clock
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    execvp
+ * Signature: (Ljava/lang/String;[Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_execvp
+  (JNIEnv *, jclass, jstring, jobjectArray);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    exit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_exit
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    _exit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess__1exit
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    fchdir
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_fchdir
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    fork
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_fork
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getcwd
+ * Signature: (Ljava/lang/StringBuffer;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_getcwd
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getegid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getegid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getenv
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jtux_UProcess_getenv
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    geteuid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_geteuid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getgid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getgid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getpgid
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getpgid
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getpid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getpid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getppid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getppid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getrlimit
+ * Signature: (ILjtux/UProcess$s_rlimit;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_getrlimit
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getrusage
+ * Signature: (ILjtux/UProcess$s_rusage;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_getrusage
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getsid
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getsid
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    getuid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getuid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    kill
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_kill
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    nice
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_nice
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    pause
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_pause
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    pthread_sigmask
+ * Signature: (ILjtux/UProcess$sigset_t;Ljtux/UProcess$sigset_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_pthread_1sigmask
+  (JNIEnv *, jclass, jint, jobject, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    putenv
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_putenv
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    setenv
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Z)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_setenv
+  (JNIEnv *, jclass, jstring, jstring, jboolean);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    setegid
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_setegid
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    seteuid
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_seteuid
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    setgid
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_setgid
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    setpgid
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_setpgid
+  (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    setrlimit
+ * Signature: (ILjtux/UProcess$s_rlimit;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_setrlimit
+  (JNIEnv *, jclass, jint, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    setsid
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_setsid
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    setuid
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_setuid
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sig_get_SIGRTMIN
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UProcess_sig_1get_1SIGRTMIN
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sig_get_SIGRTMAX
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UProcess_sig_1get_1SIGRTMAX
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigaction_x
+ * Signature: (ILjtux/UProcess$s_sigaction;Ljtux/UProcess$s_sigaction;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigaction_1x
+  (JNIEnv *, jclass, jint, jobject, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigaddset
+ * Signature: (Ljtux/UProcess$sigset_t;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigaddset
+  (JNIEnv *, jclass, jobject, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigaltstack
+ * Signature: (Ljtux/UProcess$stack_t;Ljtux/UProcess$stack_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigaltstack
+  (JNIEnv *, jclass, jobject, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigdelset
+ * Signature: (Ljtux/UProcess$sigset_t;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigdelset
+  (JNIEnv *, jclass, jobject, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigemptyset
+ * Signature: (Ljtux/UProcess$sigset_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigemptyset
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigfillset
+ * Signature: (Ljtux/UProcess$sigset_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigfillset
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    siginterrupt
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_siginterrupt
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigismember
+ * Signature: (Ljtux/UProcess$sigset_t;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jtux_UProcess_sigismember
+  (JNIEnv *, jclass, jobject, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigpending
+ * Signature: (Ljtux/UProcess$sigset_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigpending
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigprocmask
+ * Signature: (ILjtux/UProcess$sigset_t;Ljtux/UProcess$sigset_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigprocmask
+  (JNIEnv *, jclass, jint, jobject, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigqueue
+ * Signature: (JILjtux/UProcess$u_sigval;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigqueue
+  (JNIEnv *, jclass, jlong, jint, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigsuspend
+ * Signature: (Ljtux/UProcess$sigset_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigsuspend
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigtimedwait
+ * Signature: (Ljtux/UProcess$sigset_t;Ljtux/UProcess$siginfo_t;Ljtux/UProcess$s_timespec;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigtimedwait
+  (JNIEnv *, jclass, jobject, jobject, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigwait
+ * Signature: (Ljtux/UProcess$sigset_t;Ljtux/UUtil$IntHolder;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigwait
+  (JNIEnv *, jclass, jobject, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    sigwaitinfo
+ * Signature: (Ljtux/UProcess$sigset_t;Ljtux/UProcess$siginfo_t;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigwaitinfo
+  (JNIEnv *, jclass, jobject, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    system
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UProcess_system
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    times
+ * Signature: (Ljtux/UProcess$s_tms;)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_times
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    umask
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_UProcess_umask
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    unsetenv
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UProcess_unsetenv
+  (JNIEnv *, jclass, jstring);
+
+/*
+ * Class:     jtux_UProcess
+ * Method:    waitpid
+ * Signature: (JLjtux/UExitStatus;I)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_waitpid
+  (JNIEnv *, jclass, jlong, jobject, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxSysVIPC.h b/JtuxSysVIPC.h
new file mode 100755
index 0000000..7087daf
--- /dev/null
+++ b/JtuxSysVIPC.h
@@ -0,0 +1,117 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_USysVIPC */
+
+#ifndef _Included_jtux_USysVIPC
+#define _Included_jtux_USysVIPC
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    ftok
+ * Signature: (Ljava/lang/String;I)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_ftok
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    msg_set_type
+ * Signature: (J[B)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msg_1set_1type
+  (JNIEnv *, jclass, jlong, jbyteArray);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    msgctl
+ * Signature: (IILjtux/USysVIPC$s_msqid_ds;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgctl
+  (JNIEnv *, jclass, jint, jint, jobject);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    msgget
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgget
+  (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    msgrcv
+ * Signature: (I[BIJI)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgrcv
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jlong, jint);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    msgsnd
+ * Signature: (I[BII)V
+ */
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgsnd
+  (JNIEnv *, jclass, jint, jbyteArray, jint, jint);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    semctl
+ * Signature: (IIILjtux/USysVIPC$u_semun;)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_semctl
+  (JNIEnv *, jclass, jint, jint, jint, jobject);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    semget
+ * Signature: (JII)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_semget
+  (JNIEnv *, jclass, jlong, jint, jint);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    semop
+ * Signature: (I[Ljtux/USysVIPC$s_sembuf;I)V
+ */
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_semop
+  (JNIEnv *, jclass, jint, jobjectArray, jint);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    shmat
+ * Signature: (IJI)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_shmat
+  (JNIEnv *, jclass, jint, jlong, jint);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    shmctl
+ * Signature: (IILjtux/USysVIPC$s_shmid_ds;)V
+ */
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmctl
+  (JNIEnv *, jclass, jint, jint, jobject);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    shmdt
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmdt
+  (JNIEnv *, jclass, jlong);
+
+/*
+ * Class:     jtux_USysVIPC
+ * Method:    shmget
+ * Signature: (JII)I
+ */
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_shmget
+  (JNIEnv *, jclass, jlong, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/JtuxUtil.h b/JtuxUtil.h
new file mode 100755
index 0000000..08fa9c7
--- /dev/null
+++ b/JtuxUtil.h
@@ -0,0 +1,61 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jtux_UUtil */
+
+#ifndef _Included_jtux_UUtil
+#define _Included_jtux_UUtil
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     jtux_UUtil
+ * Method:    check_type_sizes
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jtux_UUtil_check_1type_1sizes
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     jtux_UUtil
+ * Method:    strerror
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jtux_UUtil_strerror
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     jtux_UUtil
+ * Method:    GetSymbol
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_jtux_UUtil_GetSymbol
+  (JNIEnv *, jclass, jstring, jstring);
+
+/*
+ * Class:     jtux_UUtil
+ * Method:    GetSymbolStr
+ * Signature: (Ljava/lang/String;I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jtux_UUtil_GetSymbolStr
+  (JNIEnv *, jclass, jstring, jint);
+
+/*
+ * Class:     jtux_UUtil
+ * Method:    jaddr_to_seg
+ * Signature: (J[BI)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UUtil_jaddr_1to_1seg
+  (JNIEnv *, jclass, jlong, jbyteArray, jint);
+
+/*
+ * Class:     jtux_UUtil
+ * Method:    jaddr_from_seg
+ * Signature: (J[BI)V
+ */
+JNIEXPORT void JNICALL Java_jtux_UUtil_jaddr_1from_1seg
+  (JNIEnv *, jclass, jlong, jbyteArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/Makefile b/Makefile
new file mode 100755
index 0000000..eaf93d0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+CC=gcc
+CFLAGS = -c -DLINUX -fPIC -I/usr/local/j2sdk/include/ -I/usr/local/j2sdk/include/linux -Wimplicit -Wstrict-prototypes -Wall -Wno-unknown-pragmas -Iinclude
+BINDIR=/usr/local/bin
+
+OBJFILES=jtux_clock.o jtux_file.o jtux_posixipc.o jtux_sysvipc.o jtux_dir.o jtux_network.o jtux_process.o jtux_util.o
+
+libjtux.so: $(OBJFILES)
+	$(CC) -shared -W1 -lrt -lnsl -o libjtux.so $(OBJFILES)
+
+clean:
+	rm -f *.o libjtux.so *.c~ *.h~ *.class
diff --git a/include/defs.h b/include/defs.h
new file mode 100755
index 0000000..ce298c4
--- /dev/null
+++ b/include/defs.h
@@ -0,0 +1,135 @@
+/*
+	Common header file
+	AUP2, Sec. 1.06
+
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+#ifndef _DEFS_H_
+#define _DEFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _POSIX_SOURCE /* tmp */
+#error
+#endif
+
+/*
+	FREEBSD and DARWIN (Mac OS X) have many similarities, and some differences. Use BSD_DERIVED
+	to treat them the same, and the separate symbols (FREEBSD or DARWIN) to treat them
+	differently.
+*/
+#if defined(FREEBSD) || defined(DARWIN)
+#define BSD_DERIVED
+#endif
+
+#ifndef __EXTENSIONS__
+#define UNDEF__EXTENSIONS__
+#endif
+
+/*[defs1]*/
+#if !defined(BSD_DERIVED) /* _POSIX_SOURCE too restrictive */
+#define SUV_SUS2
+#include "suvreq.h"
+#endif
+
+#ifdef __GNUC__
+#undef _GNU_SOURCE
+#define _GNU_SOURCE /* bring GNU as close to C99 as possible */
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#if !defined(__cplusplus) && !defined(SKIP_BOOL)
+#include <stdbool.h> /* C99 only */
+#endif
+/*[]*/
+#include <signal.h>
+
+#if defined(SOLARIS) || defined(HPUX)
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__ /* sys/stat.h won't compile without this */
+#endif
+#endif
+#include <sys/stat.h>
+#if defined(SOLARIS) || defined(HPUX)
+#ifdef UNDEF__EXTENSIONS__
+#undef __EXTENSIONS__
+#endif
+#endif
+
+/*[defs2]*/
+#include <time.h>
+#include <limits.h>
+#if defined(SOLARIS)
+#define _VA_LIST /* can't define it in stdio.h */
+#endif
+#include <stdio.h>
+#if defined(SOLARIS)
+#undef _VA_LIST
+#endif
+#include <stdarg.h> /* this is the place to define _VA_LIST */
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <assert.h>
+#ifndef AUP2_SKIP_WAIT
+#include <sys/wait.h>
+#endif
+#include "ec.h"
+/*[]*/
+#include "logf.h"
+#include "options.h"
+#include "macrostr.h"
+#include "extio.h"
+
+/*
+	File-permission-bit symbols
+*/
+/*[defs-perm]*/
+#define PERM_DIRECTORY	S_IRWXU
+#define PERM_FILE		(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+/*[]*/
+
+bool setblock(int fd, bool on); /* also in c4/setblock.h */
+#define syserrmsg(buf, buf_max, msg, s_errno)\
+  syserrmsgtype(buf, buf_max, msg, s_errno, EC_ERRNO)
+char *syserrmsgtype(char *buf, size_t buf_max, const char *msg,
+  int s_errno, EC_ERRTYPE type);
+char *syserrmsgline(char *buf, size_t buf_max,
+  int s_errno, EC_ERRTYPE type);
+const char *getdate_strerror(int e);
+const char *errsymbol(int errno_arg);
+void syserr(const char *msg);
+void syserr_print(const char *msg);
+void timestart(void);
+void timestop(char *msg);
+
+unsigned long getblksize(const char *path); /* c2/getvlksize.c */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* _DEFS_H_ */
+
diff --git a/include/ec.h b/include/ec.h
new file mode 100755
index 0000000..7554b6f
--- /dev/null
+++ b/include/ec.h
@@ -0,0 +1,86 @@
+#ifndef _EC_H_
+#define _EC_H_
+
+/*
+	It might be nice to code functions or macros to replace the system calls or libraryfunctions (e.g., close_e()), but there's no way to execute a goto from an expression. So, ec_neg1(), etc., must be statements. Two alternatives:
+		1. Exit instead of goto, which is allowed in a function called within an expression.
+		2. In C++, use throw inside a function.
+	#1 doesn't allow error recovery, and #2 doesn't work in C.
+*/
+/*[basic]*/
+extern const bool ec_in_cleanup;
+
+typedef enum {EC_ERRNO = 0, EC_EAI = 1, EC_GETDATE = 2, EC_NONE = 3} EC_ERRTYPE;
+
+#define EC_CLEANUP_BGN\
+	ec_warn();\
+	ec_cleanup_bgn:\
+	{\
+		bool ec_in_cleanup;\
+		ec_in_cleanup = true;
+
+#define EC_CLEANUP_END\
+	}
+
+#define ec_cmp(var, errrtn)\
+	{\
+		assert(!ec_in_cleanup);\
+		if ((intptr_t)(var) == (intptr_t)(errrtn)) {\
+			ec_push(__func__, __FILE__, __LINE__, #var, errno, EC_ERRNO);\
+			goto ec_cleanup_bgn;\
+		}\
+	}
+
+#define ec_rv(var)\
+	{\
+		int errrtn;\
+		assert(!ec_in_cleanup);\
+		if ((errrtn = (var)) != 0) {\
+			ec_push(__func__, __FILE__, __LINE__, #var, errrtn, EC_ERRNO);\
+			goto ec_cleanup_bgn;\
+		}\
+	}
+
+#define ec_ai(var)\
+	{\
+		int errrtn;\
+		assert(!ec_in_cleanup);\
+		if ((errrtn = (var)) != 0) {\
+			ec_push(__func__, __FILE__, __LINE__, #var, errrtn, EC_EAI);\
+			goto ec_cleanup_bgn;\
+		}\
+	}
+
+#define ec_neg1(x) ec_cmp(x, -1)
+/*
+	Not in book: 0 used instead of NULL to avoid warning from C++ compilers.
+*/
+#define ec_null(x) ec_cmp(x, 0)
+#define ec_zero(x) ec_null(x) /* not in book */
+#define ec_false(x) ec_cmp(x, false)
+#define ec_eof(x) ec_cmp(x, EOF)
+#define ec_nzero(x)\
+	{\
+		if ((x) != 0)\
+			EC_FAIL\
+	}
+
+#define EC_FAIL ec_cmp(0, 0)
+
+#define EC_CLEANUP goto ec_cleanup_bgn;
+
+#define EC_FLUSH(str)\
+	{\
+		ec_print();\
+		ec_reinit();\
+	}
+/*[]*/
+#define EC_EINTERNAL INT_MAX
+
+void ec_push(const char *fcn, const char *file, int line,
+  const char *str, int errno_arg, EC_ERRTYPE type);
+void ec_print(void);
+void ec_reinit(void);
+void ec_warn(void);
+
+#endif /* _EC_H_ */
diff --git a/include/extio.h b/include/extio.h
new file mode 100755
index 0000000..34e1c0d
--- /dev/null
+++ b/include/extio.h
@@ -0,0 +1,27 @@
+/*
+	writeall and readall (header)
+	AUP2, Sec. 2.09, 2.10
+
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+#ifndef _EXTIO_H_
+#define _EXTIO_H_
+
+ssize_t writeall(int fd, const void *buf, size_t nbyte);
+ssize_t readall(int fd, void *buf, size_t nbyte);
+
+#endif /* _EXTIO_H_ */
diff --git a/include/logf.h b/include/logf.h
new file mode 100755
index 0000000..f7f6e66
--- /dev/null
+++ b/include/logf.h
@@ -0,0 +1,9 @@
+#ifndef _LOGF_H_
+#define _LOGF_H_
+
+void logfmt_setpath(const char *path);
+void logfmt(const char *format, ...);
+void logfmt_args(int argc, char *argv[]);
+void logfmt_enable(bool enable);
+
+#endif /* _LOGF_H_ */
diff --git a/include/macrostr.h b/include/macrostr.h
new file mode 100755
index 0000000..8f4fd43
--- /dev/null
+++ b/include/macrostr.h
@@ -0,0 +1,6 @@
+#ifndef _MACROSTR_H_
+#define _MACROSTR_H_
+
+char *get_macrostr(const char *cat, int code, char **desc);
+
+#endif /* _MACROSTR_H_ */
diff --git a/include/macrostr.incl b/include/macrostr.incl
new file mode 100755
index 0000000..505b03f
--- /dev/null
+++ b/include/macrostr.incl
@@ -0,0 +1,366 @@
+{"errno", (intptr_t)EPERM, "EPERM", ""},
+{"errno", (intptr_t)ENOENT, "ENOENT", ""},
+{"errno", (intptr_t)ESRCH, "ESRCH", ""},
+{"errno", (intptr_t)EINTR, "EINTR", ""},
+{"errno", (intptr_t)EIO, "EIO", ""},
+{"errno", (intptr_t)ENXIO, "ENXIO", ""},
+{"errno", (intptr_t)E2BIG, "E2BIG", ""},
+{"errno", (intptr_t)ENOEXEC, "ENOEXEC", ""},
+{"errno", (intptr_t)EBADF, "EBADF", ""},
+{"errno", (intptr_t)ECHILD, "ECHILD", ""},
+{"errno", (intptr_t)EAGAIN, "EAGAIN", ""},
+{"errno", (intptr_t)ENOMEM, "ENOMEM", ""},
+{"errno", (intptr_t)EACCES, "EACCES", ""},
+{"errno", (intptr_t)EFAULT, "EFAULT", ""},
+{"errno", (intptr_t)EBUSY, "EBUSY", ""},
+{"errno", (intptr_t)EEXIST, "EEXIST", ""},
+{"errno", (intptr_t)EXDEV, "EXDEV", ""},
+{"errno", (intptr_t)ENODEV, "ENODEV", ""},
+{"errno", (intptr_t)ENOTDIR, "ENOTDIR", ""},
+{"errno", (intptr_t)EISDIR, "EISDIR", ""},
+{"errno", (intptr_t)EINVAL, "EINVAL", ""},
+{"errno", (intptr_t)ENFILE, "ENFILE", ""},
+{"errno", (intptr_t)EMFILE, "EMFILE", ""},
+{"errno", (intptr_t)ENOTTY, "ENOTTY", ""},
+{"errno", (intptr_t)EFBIG, "EFBIG", ""},
+{"errno", (intptr_t)ENOSPC, "ENOSPC", ""},
+{"errno", (intptr_t)ESPIPE, "ESPIPE", ""},
+{"errno", (intptr_t)EROFS, "EROFS", ""},
+{"errno", (intptr_t)EMLINK, "EMLINK", ""},
+{"errno", (intptr_t)EPIPE, "EPIPE", ""},
+{"errno", (intptr_t)EDOM, "EDOM", ""},
+{"errno", (intptr_t)ERANGE, "ERANGE", ""},
+{"errno", (intptr_t)EDEADLK, "EDEADLK", ""},
+{"errno", (intptr_t)ENAMETOOLONG, "ENAMETOOLONG", ""},
+{"errno", (intptr_t)ENOLCK, "ENOLCK", ""},
+{"errno", (intptr_t)ENOSYS, "ENOSYS", ""},
+{"errno", (intptr_t)ENOTEMPTY, "ENOTEMPTY", ""},
+#ifndef BSD_DERIVED
+{"errno", (intptr_t)ECHRNG, "ECHRNG", ""},
+{"errno", (intptr_t)EL2NSYNC, "EL2NSYNC", ""},
+{"errno", (intptr_t)EL3HLT, "EL3HLT", ""},
+{"errno", (intptr_t)EL3RST, "EL3RST", ""},
+{"errno", (intptr_t)ELNRNG, "ELNRNG", ""},
+{"errno", (intptr_t)EUNATCH, "EUNATCH", ""},
+{"errno", (intptr_t)ENOCSI, "ENOCSI", ""},
+{"errno", (intptr_t)EL2HLT, "EL2HLT", ""},
+#ifndef HPUX
+{"errno", (intptr_t)EBADE, "EBADE", ""},
+{"errno", (intptr_t)EBADR, "EBADR", ""},
+{"errno", (intptr_t)EXFULL, "EXFULL", ""},
+{"errno", (intptr_t)ENOANO, "ENOANO", ""},
+{"errno", (intptr_t)EBADRQC, "EBADRQC", ""},
+{"errno", (intptr_t)EBADSLT, "EBADSLT", ""},
+{"errno", (intptr_t)EDEADLOCK, "EDEADLOCK", ""},
+{"errno", (intptr_t)EBFONT, "EBFONT", ""},
+{"errno", (intptr_t)ENOTUNIQ, "ENOTUNIQ", ""},
+{"errno", (intptr_t)EBADFD, "EBADFD", ""},
+{"errno", (intptr_t)EREMCHG, "EREMCHG", ""},
+{"errno", (intptr_t)ELIBACC, "ELIBACC", ""},
+{"errno", (intptr_t)ELIBBAD, "ELIBBAD", ""},
+{"errno", (intptr_t)ELIBSCN, "ELIBSCN", ""},
+{"errno", (intptr_t)ELIBMAX, "ELIBMAX", ""},
+{"errno", (intptr_t)ELIBEXEC, "ELIBEXEC", ""},
+{"errno", (intptr_t)ERESTART, "ERESTART", ""},
+{"errno", (intptr_t)ESTRPIPE, "ESTRPIPE", ""},
+#endif
+{"errno", (intptr_t)ENOSTR, "ENOSTR", ""},
+{"errno", (intptr_t)ENODATA, "ENODATA", ""},
+{"errno", (intptr_t)ETIME, "ETIME", ""},
+{"errno", (intptr_t)ENOSR, "ENOSR", ""},
+{"errno", (intptr_t)ENONET, "ENONET", ""},
+{"errno", (intptr_t)ENOPKG, "ENOPKG", ""},
+{"errno", (intptr_t)ENOLINK, "ENOLINK", ""},
+{"errno", (intptr_t)EADV, "EADV", ""},
+{"errno", (intptr_t)ESRMNT, "ESRMNT", ""},
+{"errno", (intptr_t)ECOMM, "ECOMM", ""},
+{"errno", (intptr_t)EPROTO, "EPROTO", ""},
+{"errno", (intptr_t)EMULTIHOP, "EMULTIHOP", ""},
+{"errno", (intptr_t)EBADMSG, "EBADMSG", ""},
+{"errno", (intptr_t)EDQUOT, "EDQUOT", ""},
+#ifndef SOLARIS
+{"errno", (intptr_t)EDOTDOT, "EDOTDOT", ""},
+#ifndef HPUX
+{"errno", (intptr_t)EUCLEAN, "EUCLEAN", ""},
+{"errno", (intptr_t)ENOTNAM, "ENOTNAM", ""},
+{"errno", (intptr_t)ENAVAIL, "ENAVAIL", ""},
+{"errno", (intptr_t)EISNAM, "EISNAM", ""},
+{"errno", (intptr_t)EREMOTEIO, "EREMOTEIO", ""},
+{"errno", (intptr_t)ENOMEDIUM, "ENOMEDIUM", ""},
+{"errno", (intptr_t)EMEDIUMTYPE, "EMEDIUMTYPE", ""},
+#endif
+#endif /* SOLARIS */
+#endif /* BSD_DRIVED */
+#ifndef _POSIX_SOURCE
+{"errno", (intptr_t)ENOTBLK, "ENOTBLK", ""},
+{"errno", (intptr_t)ETXTBSY, "ETXTBSY", ""},
+{"errno", (intptr_t)ENOTSOCK, "ENOTSOCK", ""},
+{"errno", (intptr_t)EDESTADDRREQ, "EDESTADDRREQ", ""},
+{"errno", (intptr_t)EMSGSIZE, "EMSGSIZE", ""},
+{"errno", (intptr_t)EPROTOTYPE, "EPROTOTYPE", ""},
+{"errno", (intptr_t)ENOPROTOOPT, "ENOPROTOOPT", ""},
+{"errno", (intptr_t)EPROTONOSUPPORT, "EPROTONOSUPPORT", ""},
+{"errno", (intptr_t)ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", ""},
+{"errno", (intptr_t)EOPNOTSUPP, "EOPNOTSUPP", ""},
+{"errno", (intptr_t)EPFNOSUPPORT, "EPFNOSUPPORT", ""},
+{"errno", (intptr_t)EAFNOSUPPORT, "EAFNOSUPPORT", ""},
+{"errno", (intptr_t)EADDRINUSE, "EADDRINUSE", ""},
+{"errno", (intptr_t)EADDRNOTAVAIL, "EADDRNOTAVAIL", ""},
+{"errno", (intptr_t)ENETDOWN, "ENETDOWN", ""},
+{"errno", (intptr_t)ENETUNREACH, "ENETUNREACH", ""},
+{"errno", (intptr_t)ENETRESET, "ENETRESET", ""},
+{"errno", (intptr_t)ECONNABORTED, "ECONNABORTED", ""},
+{"errno", (intptr_t)ECONNRESET, "ECONNRESET", ""},
+{"errno", (intptr_t)ENOBUFS, "ENOBUFS", ""},
+{"errno", (intptr_t)EISCONN, "EISCONN", ""},
+{"errno", (intptr_t)ENOTCONN, "ENOTCONN", ""},
+{"errno", (intptr_t)ESHUTDOWN, "ESHUTDOWN", ""},
+{"errno", (intptr_t)ETOOMANYREFS, "ETOOMANYREFS", ""},
+{"errno", (intptr_t)ETIMEDOUT, "ETIMEDOUT", ""},
+{"errno", (intptr_t)ECONNREFUSED, "ECONNREFUSED", ""},
+{"errno", (intptr_t)ELOOP, "ELOOP", ""},
+{"errno", (intptr_t)EWOULDBLOCK, "EWOULDBLOCK", ""},
+{"errno", (intptr_t)EALREADY, "EALREADY", ""},
+{"errno", (intptr_t)EINPROGRESS, "EINPROGRESS", ""},
+{"errno", (intptr_t)EHOSTDOWN, "EHOSTDOWN", ""},
+{"errno", (intptr_t)EHOSTUNREACH, "EHOSTUNREACH", ""},
+{"errno", (intptr_t)ESTALE, "ESTALE", ""},
+{"errno", (intptr_t)EUSERS, "EUSERS", ""},
+#ifndef DARWIN
+{"errno", (intptr_t)ENOMSG, "ENOMSG", ""},
+{"errno", (intptr_t)EIDRM, "EIDRM", ""},
+{"errno", (intptr_t)EREMOTE, "EREMOTE", ""},
+{"errno", (intptr_t)EOVERFLOW, "EOVERFLOW", ""},
+{"errno", (intptr_t)EILSEQ, "EILSEQ", ""},
+#endif /* DARWIN */
+#endif /* _POSIX_SOURCE */
+{"errno", (intptr_t)EC_EINTERNAL, "EC_EINTERNAL", ""},
+#ifndef DARWIN
+{"eai", (intptr_t)EAI_ADDRFAMILY, "EAI_ADDRFAMILY", ""},
+{"eai", (intptr_t)EAI_AGAIN, "EAI_AGAIN", ""},
+{"eai", (intptr_t)EAI_BADFLAGS, "EAI_BADFLAGS", ""},
+{"eai", (intptr_t)EAI_FAIL, "EAI_FAIL", ""},
+{"eai", (intptr_t)EAI_FAMILY, "EAI_FAMILY", ""},
+{"eai", (intptr_t)EAI_MEMORY, "EAI_MEMORY", ""},
+{"eai", (intptr_t)EAI_NONAME, "EAI_NONAME", ""},
+{"eai", (intptr_t)EAI_SERVICE, "EAI_SERVICE", ""},
+{"eai", (intptr_t)EAI_SOCKTYPE, "EAI_SOCKTYPE", ""},
+{"eai", (intptr_t)EAI_SYSTEM, "EAI_SYSTEM", ""},
+#ifdef EAI_OVERFLOW
+{"eai", (intptr_t)EAI_OVERFLOW, "EAI_OVERFLOW", ""},
+#endif
+#endif /* DARWIN */
+{"sigaction", (intptr_t)SIG_DFL, "SIG_DFL", ""},
+{"sigaction", (intptr_t)SIG_IGN, "SIG_IGN", ""},
+{"sigaction", (intptr_t)SIG_ERR, "SIG_ERR", ""},
+{"sigaction_flags", (intptr_t)SA_NOCLDSTOP, "SA_NOCLDSTOP", ""},
+{"sigaction_flags", (intptr_t)SA_NOCLDWAIT, "SA_NOCLDWAIT", ""},
+{"sigaction_flags", (intptr_t)SA_NODEFER, "SA_NODEFER", ""},
+{"sigaction_flags", (intptr_t)SA_ONSTACK, "SA_ONSTACK", ""},
+{"sigaction_flags", (intptr_t)SA_RESETHAND, "SA_RESETHAND", ""},
+{"sigaction_flags", (intptr_t)SA_RESTART, "SA_RESTART", ""},
+{"sigaction_flags", (intptr_t)SA_SIGINFO, "SA_SIGINFO", ""},
+{"sigprocmask", (intptr_t)SIG_BLOCK, "SIG_BLOCK", ""},
+{"sigprocmask", (intptr_t)SIG_SETMASK, "SIG_SETMASK", ""},
+{"sigprocmask", (intptr_t)SIG_UNBLOCK, "SIG_UNBLOCK", ""},
+{"signal", (intptr_t)SIGABRT, "SIGABRT", "Process abort signal"},
+{"signal", (intptr_t)SIGALRM, "SIGALRM", "Alarm clock"},
+{"signal", (intptr_t)SIGBUS, "SIGBUS", "Access to undefined portion of memory object"},
+{"signal", (intptr_t)SIGCHLD, "SIGCHLD", "Child terminated, stopped, or continued."},
+{"signal", (intptr_t)SIGCONT, "SIGCONT", "Continue executing, if stopped"},
+{"signal", (intptr_t)SIGFPE, "SIGFPE", "Erroneous arithmetic operation"},
+{"signal", (intptr_t)SIGHUP, "SIGHUP", "Hangup"},
+{"signal", (intptr_t)SIGILL, "SIGILL", "Illegal instruction"},
+{"signal", (intptr_t)SIGINT, "SIGINT", "Terminal interrupt signal"},
+{"signal", (intptr_t)SIGKILL, "SIGKILL", "Kill (cannot be caught or ignored)"},
+{"signal", (intptr_t)SIGPIPE, "SIGPIPE", "Write on a pipe with no one to read it"},
+{"signal", (intptr_t)SIGQUIT, "SIGQUIT", "Terminal quit signal"},
+{"signal", (intptr_t)SIGSEGV, "SIGSEGV", "Invalid memory reference"},
+{"signal", (intptr_t)SIGSTOP, "SIGSTOP", "Stop executing (cannot be caught or ignored)"},
+{"signal", (intptr_t)SIGTERM, "SIGTERM", "Termination signal"},
+{"signal", (intptr_t)SIGTSTP, "SIGTSTP", "Terminal stop signal"},
+{"signal", (intptr_t)SIGTTIN, "SIGTTIN", "Background process attempting read"},
+{"signal", (intptr_t)SIGTTOU, "SIGTTOU", "Background process attempting write"},
+{"signal", (intptr_t)SIGUSR1, "SIGUSR1", "User-defined signal 1"},
+{"signal", (intptr_t)SIGUSR2, "SIGUSR2", "User-defined signal 2"},
+#ifdef _XOPEN_UNIX
+{"signal", (intptr_t)SIGPOLL, "SIGPOLL", "Pollable event"},
+#endif
+{"signal", (intptr_t)SIGPROF, "SIGPROF", "Profiling timer expired"},
+{"signal", (intptr_t)SIGSYS, "SIGSYS", "Bad system call"},
+{"signal", (intptr_t)SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"},
+{"signal", (intptr_t)SIGURG, "SIGURG", "High bandwidth data is available at a socket"},
+{"signal", (intptr_t)SIGVTALRM, "SIGVTALRM", "Virtual timer expired"},
+{"signal", (intptr_t)SIGXCPU, "SIGXCPU", "CPU time limit exceeded"},
+{"signal", (intptr_t)SIGXFSZ, "SIGXFSZ", "File size limit exceeded"},
+#ifdef _XOPEN_UNIX
+{"sigchld-code", (intptr_t)CLD_EXITED, "CLD_EXITED", ""},
+{"sigchld-code", (intptr_t)CLD_KILLED, "CLD_KILLED", ""},
+{"sigchld-code", (intptr_t)CLD_DUMPED, "CLD_DUMPED", ""},
+{"sigchld-code", (intptr_t)CLD_TRAPPED, "CLD_TRAPPED", ""},
+{"sigchld-code", (intptr_t)CLD_STOPPED, "CLD_STOPPED", ""},
+{"sigchld-code", (intptr_t)CLD_CONTINUED, "CLD_CONTINUED", ""},
+#endif
+{"fcntl", (intptr_t)O_APPEND, "O_APPEND", ""},
+{"fcntl", (intptr_t)O_CREAT, "O_CREAT", ""},
+#ifndef BSD_DERIVED
+{"fcntl", (intptr_t)O_DSYNC, "O_DSYNC", ""},
+#endif /* BSD_DERIVED */
+{"fcntl", (intptr_t)O_EXCL, "O_EXCL", ""},
+{"fcntl", (intptr_t)O_NOCTTY, "O_NOCTTY", ""},
+{"fcntl", (intptr_t)O_NONBLOCK, "O_NONBLOCK", ""},
+#ifndef BSD_DERIVED
+{"fcntl", (intptr_t)O_RSYNC, "O_RSYNC", ""},
+{"fcntl", (intptr_t)O_SYNC, "O_SYNC", ""},
+#endif /* BSD_DERIVED */
+{"fcntl", (intptr_t)O_TRUNC, "O_TRUNC", ""},
+{"fcntl_io", (intptr_t)O_RDONLY, "O_RDONLY", ""},
+{"fcntl_io", (intptr_t)O_RDWR, "O_RDWR", ""},
+{"fcntl_io", (intptr_t)O_WRONLY, "O_WRONLY", ""},
+#ifndef BSD_DERIVED
+{"rusage", (intptr_t)RUSAGE_SELF, "RUSAGE_SELF", ""},
+{"rusage", (intptr_t)RUSAGE_CHILDREN, "RUSAGE_CHILDREN", ""},
+{"rlimit", (intptr_t)RLIMIT_CORE, "RLIMIT_CORE", ""},
+{"rlimit", (intptr_t)RLIMIT_CPU, "RLIMIT_CPU", ""},
+{"rlimit", (intptr_t)RLIMIT_DATA, "RLIMIT_DATA", ""},
+{"rlimit", (intptr_t)RLIMIT_FSIZE, "RLIMIT_FSIZE", ""},
+{"rlimit", (intptr_t)RLIMIT_NOFILE, "RLIMIT_NOFILE", ""},
+{"rlimit", (intptr_t)RLIMIT_STACK, "RLIMIT_STACK", ""},
+{"rlimit", (intptr_t)RLIMIT_AS, "RLIMIT_AS", ""},
+#endif /* BSD_DERIVED */
+{"clock", (intptr_t)CLOCKS_PER_SEC, "CLOCKS_PER_SEC", ""},
+{"stdfileno", (intptr_t)STDIN_FILENO, "STDIN_FILENO", ""},
+{"stdfileno", (intptr_t)STDOUT_FILENO, "STDOUT_FILENO", ""},
+{"stdfileno", (intptr_t)STDERR_FILENO, "STDERR_FILENO", ""},
+{"perm", (intptr_t)S_IRUSR, "S_IRUSR", ""},
+{"perm", (intptr_t)S_IWUSR, "S_IWUSR", ""},
+{"perm", (intptr_t)S_IXUSR, "S_IXUSR", ""},
+{"perm", (intptr_t)S_IRGRP, "S_IRGRP", ""},
+{"perm", (intptr_t)S_IWGRP, "S_IWGRP", ""},
+{"perm", (intptr_t)S_IXGRP, "S_IXGRP", ""},
+{"perm", (intptr_t)S_IROTH, "S_IROTH", ""},
+{"perm", (intptr_t)S_IWOTH, "S_IWOTH", ""},
+{"perm", (intptr_t)S_IXOTH, "S_IXOTH", ""},
+{"perm", (intptr_t)S_ISUID, "S_ISUID", ""},
+{"perm", (intptr_t)S_ISGID, "S_ISGID", ""},
+{"perm", (intptr_t)S_ISVTX, "S_ISVTX", ""},
+{"lseek", (intptr_t)SEEK_SET, "SEEK_SET", ""},
+{"lseek", (intptr_t)SEEK_CUR, "SEEK_CUR", ""},
+{"lseek", (intptr_t)SEEK_END, "SEEK_END", ""},
+{"st_mode", (intptr_t)S_IFMT, "S_IFMT", ""},
+{"st_mode", (intptr_t)S_IFBLK, "S_IFBLK", ""},
+{"st_mode", (intptr_t)S_IFCHR, "S_IFCHR", ""},
+{"st_mode", (intptr_t)S_IFDIR, "S_IFDIR", ""},
+{"st_mode", (intptr_t)S_IFIFO, "S_IFIFO", ""},
+{"st_mode", (intptr_t)S_IFLNK, "S_IFLNK", ""},
+{"st_mode", (intptr_t)S_IFREG, "S_IFREG", ""},
+{"st_mode", (intptr_t)S_IFSOCK, "S_IFSOCK", ""},
+{"access", (intptr_t)R_OK, "R_OK", ""},
+{"access", (intptr_t)W_OK, "W_OK", ""},
+{"access", (intptr_t)X_OK, "X_OK", ""},
+{"access", (intptr_t)F_OK, "F_OK", ""},
+{"fcntl_op", (intptr_t)F_DUPFD, "F_DUPFD", ""},
+{"fcntl_op", (intptr_t)F_GETFD, "F_GETFD", ""},
+{"fcntl_op", (intptr_t)F_SETFD, "F_SETFD", ""},
+{"fcntl_op", (intptr_t)F_GETFL, "F_GETFL", ""},
+{"fcntl_op", (intptr_t)F_SETFL, "F_SETFL", ""},
+{"fcntl_op", (intptr_t)F_GETOWN, "F_GETOWN", ""},
+{"fcntl_op", (intptr_t)F_SETOWN, "F_SETOWN", ""},
+{"fcntl_op", (intptr_t)F_GETLK, "F_GETLK", ""},
+{"fcntl_op", (intptr_t)F_SETLK, "F_SETLK", ""},
+{"fcntl_op", (intptr_t)F_SETLKW, "F_SETLKW", ""},
+{"fcntl_fd", (intptr_t)FD_CLOEXEC, "FD_CLOEXEC", ""},
+{"lockf", (intptr_t)F_LOCK, "F_LOCK", ""},
+{"lockf", (intptr_t)F_TLOCK, "F_TLOCK", ""},
+{"lockf", (intptr_t)F_TEST, "F_TEST", ""},
+{"lockf", (intptr_t)F_ULOCK, "F_ULOCK", ""},
+{"exit", (intptr_t)EXIT_SUCCESS, "EXIT_SUCCESS", ""},
+{"exit", (intptr_t)EXIT_FAILURE, "EXIT_FAILURE", ""},
+#if !defined(BSD_DERIVED) && !defined(LINUX) && !defined(HPUX)
+{"poll", (intptr_t)POLLRDNORM, "POLLRDNORM", ""},
+{"poll", (intptr_t)POLLRDBAND, "POLLRDBAND", ""},
+{"poll", (intptr_t)POLLIN, "POLLIN", ""},
+{"poll", (intptr_t)POLLPRI, "POLLPRI", ""},
+{"poll", (intptr_t)POLLWRNORM, "POLLWRNORM", ""},
+{"poll", (intptr_t)POLLOUT, "POLLOUT", ""},
+{"poll", (intptr_t)POLLWRBAND, "POLLWRBAND", ""},
+{"poll", (intptr_t)POLLERR, "POLLERR", ""},
+{"poll", (intptr_t)POLLHUP, "POLLHUP", ""},
+{"poll", (intptr_t)POLLNVAL, "POLLNVAL", ""},
+#endif /* BSD_DERIVED */
+{"SysVIPC_mode", (intptr_t)IPC_CREAT, "IPC_CREAT", ""},
+{"SysVIPC_mode", (intptr_t)IPC_EXCL, "IPC_EXCL", ""},
+{"SysVIPC_mode", (intptr_t)IPC_NOWAIT, "IPC_NOWAIT", ""},
+{"SysVIPC_key", (intptr_t)IPC_PRIVATE, "IPC_PRIVATE", ""},
+{"SysVIPC_cmd", (intptr_t)IPC_RMID, "IPC_RMID", ""},
+{"SysVIPC_cmd", (intptr_t)IPC_STAT, "IPC_STAT", ""},
+{"SysVIPC_cmd", (intptr_t)IPC_SET, "IPC_SET", ""},
+{"SysVIPC_cmd", (intptr_t)GETNCNT, "GETNCNT", ""},
+{"SysVIPC_cmd", (intptr_t)GETZCNT, "GETZCNT", ""},
+{"SysVIPC_cmd", (intptr_t)GETPID, "GETPID", ""},
+{"SysVIPC_cmd", (intptr_t)GETVAL, "GETVAL", ""},
+{"SysVIPC_cmd", (intptr_t)SETVAL, "SETVAL", ""},
+{"SysVIPC_cmd", (intptr_t)GETALL, "GETALL", ""},
+{"SysVIPC_cmd", (intptr_t)SETALL, "SETALL", ""},
+{"SysVIPC_shm", (intptr_t)SHM_RND, "SHM_RND", ""},
+{"SysVIPC_shm", (intptr_t)SHM_RDONLY, "SHM_RDONLY", ""},
+{"mmap", (intptr_t)PROT_READ, "PROT_READ", ""},
+{"mmap", (intptr_t)PROT_WRITE, "PROT_WRITE", ""},
+{"mmap", (intptr_t)PROT_EXEC, "PROT_EXEC", ""},
+{"mmap_flags", (intptr_t)MAP_SHARED, "MAP_SHARED", ""},
+{"mmap_flags", (intptr_t)MAP_PRIVATE, "MAP_PRIVATE", ""},
+{"mmap_flags", (intptr_t)MAP_FIXED, "MAP_FIXED", ""},
+{"sigevent", (intptr_t)SIGEV_SIGNAL, "SIGEV_SIGNAL", ""},
+#ifndef FREEBSD
+{"sigevent", (intptr_t)SIGEV_THREAD, "SIGEV_THREAD", ""},
+#endif /* FREEBSD */
+{"sigevent", (intptr_t)SIGEV_NONE, "SIGEV_NONE", ""},
+{"skt_domain", (intptr_t)AF_UNIX, "AF_UNIX", ""},
+{"skt_domain", (intptr_t)AF_INET, "AF_INET", ""},
+{"skt_domain", (intptr_t)AF_INET6, "AF_INET6", ""},
+{"skt_domain", (intptr_t)AF_UNSPEC, "AF_UNSPEC", ""},
+{"skt_type", (intptr_t)SOCK_DGRAM, "SOCK_DGRAM", ""},
+{"skt_type", (intptr_t)SOCK_RAW, "SOCK_RAW", ""},
+{"skt_type", (intptr_t)SOCK_SEQPACKET, "SOCK_SEQPACKET", ""},
+{"skt_type", (intptr_t)SOCK_STREAM, "SOCK_STREAM", ""},
+{"skt_level", (intptr_t)SOL_SOCKET, "SOL_SOCKET", ""},
+{"skt_option", (intptr_t)SO_ACCEPTCONN, "SO_ACCEPTCONN", ""},
+{"skt_option", (intptr_t)SO_BROADCAST, "SO_BROADCAST", ""},
+{"skt_option", (intptr_t)SO_DEBUG, "SO_DEBUG", ""},
+{"skt_option", (intptr_t)SO_DONTROUTE, "SO_DONTROUTE", ""},
+{"skt_option", (intptr_t)SO_ERROR, "SO_ERROR", ""},
+{"skt_option", (intptr_t)SO_KEEPALIVE, "SO_KEEPALIVE", ""},
+{"skt_option", (intptr_t)SO_LINGER, "SO_LINGER", ""},
+{"skt_option", (intptr_t)SO_OOBINLINE, "SO_OOBINLINE", ""},
+{"skt_option", (intptr_t)SO_RCVBUF, "SO_RCVBUF", ""},
+{"skt_option", (intptr_t)SO_RCVLOWAT, "SO_RCVLOWAT", ""},
+{"skt_option", (intptr_t)SO_RCVTIMEO, "SO_RCVTIMEO", ""},
+{"skt_option", (intptr_t)SO_REUSEADDR, "SO_REUSEADDR", ""},
+{"skt_option", (intptr_t)SO_SNDBUF, "SO_SNDBUF", ""},
+{"skt_option", (intptr_t)SO_SNDLOWAT, "SO_SNDLOWAT", ""},
+{"skt_option", (intptr_t)SO_SNDTIMEO, "SO_SNDTIMEO", ""},
+{"skt_option", (intptr_t)SO_TYPE, "SO_TYPE", ""},
+{"skt_backlog", (intptr_t)SOMAXCONN, "SOMAXCONN", ""},
+{"skt_msg_flag", (intptr_t)MSG_CTRUNC, "MSG_CTRUNC", ""},
+{"skt_msg_flag", (intptr_t)MSG_DONTROUTE, "MSG_DONTROUTE", ""},
+{"skt_msg_flag", (intptr_t)MSG_EOR, "MSG_EOR", ""},
+{"skt_msg_flag", (intptr_t)MSG_OOB, "MSG_OOB", ""},
+{"skt_msg_flag", (intptr_t)MSG_PEEK, "MSG_PEEK", ""},
+{"skt_msg_flag", (intptr_t)MSG_TRUNC, "MSG_TRUNC", ""},
+{"skt_msg_flag", (intptr_t)MSG_WAITALL, "MSG_WAITALL", ""},
+{"skt_shut", (intptr_t)SHUT_RD, "SHUT_RD", ""},
+{"skt_shut", (intptr_t)SHUT_RDWR, "SHUT_RDWR", ""},
+{"skt_shut", (intptr_t)SHUT_WR, "SHUT_WR", ""},
+{"skt_cmsg_type", (intptr_t)SCM_RIGHTS, "SCM_RIGHTS", ""},
+{"getaddrinfo", (intptr_t)AI_PASSIVE, "AI_PASSIVE", ""},
+{"getnameinfo", (intptr_t)NI_NOFQDN, "NI_NOFQDN", ""},
+{"getnameinfo", (intptr_t)NI_NUMERICHOST, "NI_NUMERICHOST", ""},
+{"getnameinfo", (intptr_t)NI_NAMEREQD, "NI_NAMEREQD", ""},
+{"getnameinfo", (intptr_t)NI_NUMERICSERV, "NI_NUMERICSERV", ""},
+{"getnameinfo", (intptr_t)NI_DGRAM, "NI_DGRAM", ""},
+{"sockopt_level", (intptr_t)IPPROTO_IP, "IPPROTO_IP", ""},
+{"sockopt_level", (intptr_t)IPPROTO_IPV6, "IPPROTO_IPV6", ""},
+{"sockopt_level", (intptr_t)IPPROTO_ICMP, "IPPROTO_ICMP", ""},
+{"sockopt_level", (intptr_t)IPPROTO_RAW, "IPPROTO_RAW", ""},
+{"sockopt_level", (intptr_t)IPPROTO_TCP, "IPPROTO_TCP", ""},
+{"sockopt_level", (intptr_t)IPPROTO_UDP, "IPPROTO_UDP", ""},
diff --git a/include/options.h b/include/options.h
new file mode 100755
index 0000000..765bf22
--- /dev/null
+++ b/include/options.h
@@ -0,0 +1,11 @@
+#ifndef _OPTIONS_H_
+#define _OPTIONS_H_
+
+/*[enum-OPT_RETURN]*/
+typedef enum {OPT_NO = 0, OPT_YES = 1, OPT_ERROR = -1} OPT_RETURN;
+/*[]*/
+
+OPT_RETURN option_sync_io(const char *path);
+OPT_RETURN option_async_io(const char *path);
+
+#endif /* _OPTIONS_H_ */
diff --git a/include/suvreq.h b/include/suvreq.h
new file mode 100755
index 0000000..e28e584
--- /dev/null
+++ b/include/suvreq.h
@@ -0,0 +1,72 @@
+/*
+	Asking the system what it has (header)
+	AUP2, Sec. 1.05.3
+
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+#ifndef _SUVREQ_H_
+#define _SUVREQ_H_
+/*[suvreq-h]*/
+/*
+	Header to request specific standard support. Before including it, one
+	of the following symbols must be defined (1003.1-1988 isn't supported):
+
+		SUV_POSIX1990	for 1003.1-1990
+		SUV_POSIX1993	for 1003.1b-1993 - real-time
+		SUV_POSIX1996	for 1003.1-1996
+		SUV_SUS1		for Single UNIX Specification, v. 1 (UNIX 95)
+		SUV_SUS2		for Single UNIX Specification, v. 2 (UNIX 98)
+		SUV_SUS3		for Single UNIX Specification, v. 3
+*/
+
+#ifdef _POSIX_SOURCE /* tmp */
+#error
+#endif
+
+#if defined(SUV_POSIX1990)
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 1
+
+#elif defined(SUV_POSIX1993)
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 199309L
+
+#elif defined(SUV_POSIX1996)
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 199506L
+
+#elif defined(SUV_SUS1)
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 2
+#define _XOPEN_SOURCE
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#elif defined(SUV_SUS2)
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 199506L
+#define _XOPEN_SOURCE 500
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#elif defined(SUV_SUS3)
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 200112L
+#define _XOPEN_SOURCE 600
+#define _XOPEN_SOURCE_EXTENDED 1
+#endif
+/*[]*/
+
+#endif /* _SUVREQ_H_ */
diff --git a/jtux_clock.c b/jtux_clock.c
new file mode 100755
index 0000000..e603e6e
--- /dev/null
+++ b/jtux_clock.c
@@ -0,0 +1,67 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+
+#include "defs.h"
+#include "JtuxClock.h" // generated by javah
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+JNIEXPORT jint JNICALL Java_jtux_UClock_alarm(JNIEnv *env, jclass obj,
+  jint secs)
+{
+	return alarm(secs);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UClock_nanosleep(JNIEnv *env, jclass obj,
+  jobject nsecs, jobject remain)
+{
+	jclass cls_timespec = (*env)->FindClass(env, "jtux/UProcess$s_timespec");
+	struct timespec nsecs_c, remain_buf, *remain_c = &remain_buf;
+	int r;
+	long sec;
+
+	if (remain == NULL)
+		remain_c = NULL;
+	if (!field_jtoc_long(env, cls_timespec, "tv_sec", nsecs, &sec))
+		return;
+	nsecs_c.tv_sec = (time_t)sec;
+	if (!field_jtoc_long(env, cls_timespec, "tv_nsec", nsecs, &nsecs_c.tv_nsec))
+		return;
+	r = nanosleep(&nsecs_c, remain_c);
+	if (r != 0 && remain_c != NULL) {
+		if (!field_ctoj_long(env, cls_timespec, "tv_sec", remain, remain_c->tv_sec))
+			return;
+		if (!field_ctoj_long(env, cls_timespec, "tv_nsec", remain, remain_c->tv_nsec))
+			return;
+	}
+	if (r == -1)
+		JTHROW_neg1(-1);
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UClock_sleep(JNIEnv *env, jclass obj,
+  jint secs)
+{
+	return sleep(secs);
+}
+
+
+JNIEXPORT void JNICALL Java_jtux_UClock_usleep(JNIEnv *env, jclass obj,
+  jint usecs)
+{
+	JTHROW_neg1(usleep(usecs))
+}
diff --git a/jtux_dir.c b/jtux_dir.c
new file mode 100755
index 0000000..3decbb9
--- /dev/null
+++ b/jtux_dir.c
@@ -0,0 +1,130 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+
+#include "defs.h"
+#include <dirent.h>
+#include "JtuxDir.h" // generated by javah
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+JNIEXPORT void JNICALL Java_jtux_UDir_closedir(JNIEnv *env, jclass obj,
+  jlong dirp)
+{
+	JTHROW_neg1(closedir((DIR *)(intptr_t)dirp))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UDir_mkdir(JNIEnv *env, jclass obj,
+  jstring path, jint mode)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(mkdir(path_c, mode))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UDir_opendir(JNIEnv *env, jclass obj,
+  jstring path)
+{
+	DIR *dirp;
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST_V(path_c, 0)
+	JTHROW_null(dirp = opendir(path_c))
+	JSTR_REL(path_c, path)
+	return (intptr_t)dirp;
+}
+
+JNIEXPORT jobject JNICALL Java_jtux_UDir_readdir(JNIEnv *env, jclass obj,
+  jlong dirp)
+{
+	jclass cls_s_dirent = (*env)->FindClass(env, "jtux/UDir$s_dirent");
+	jobject dirent;
+	jmethodID mid;
+	long name_max;
+	int r;
+	struct dirent *entry, *result;
+
+	errno = 0;
+	if ((name_max = pathconf(".", _PC_NAME_MAX)) == -1) {
+		if (errno == 0)
+			name_max = 1000; // no limit -- take a guess
+		else {
+			JTHROW_neg1(-1);
+			return NULL;
+		}
+	}
+	JTHROW_null(entry = malloc(offsetof(struct dirent, d_name) + name_max + 1))
+	if (entry == NULL)
+		return NULL;
+	JTHROW_rv(r = readdir_r((DIR *)(intptr_t)dirp, entry, &result))
+	if (r > 0 || result == NULL) {
+		free(entry);
+		return NULL;
+	}
+	if (cls_s_dirent == NULL) {
+		free(entry);
+		return NULL;
+	}
+	if ((mid = (*env)->GetMethodID(env, cls_s_dirent, "<init>", "()V")) == NULL) {
+		free(entry);
+		return NULL;
+	}
+	if ((dirent = (*env)->NewObject(env, cls_s_dirent, mid)) == NULL) {
+		free(entry);
+		return NULL;
+	}
+	if (!field_ctoj_int(env, cls_s_dirent, "d_ino", dirent, result->d_ino)) {
+		free(entry);
+		return NULL;
+	}
+	if (!field_ctoj_string(env, cls_s_dirent, "d_name", dirent, result->d_name)) {
+		free(entry);
+		return NULL;
+	}
+	free(entry);
+	return dirent;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UDir_rewinddir(JNIEnv *env, jclass obj,
+  jlong dirp)
+{
+	rewinddir((DIR *)(intptr_t)dirp);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UDir_rmdir(JNIEnv *env, jclass obj,
+  jstring path)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(rmdir(path_c))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UDir_seekdir(JNIEnv *env, jclass obj,
+  jlong dirp, jlong loc)
+{
+	seekdir((DIR *)(intptr_t)dirp, loc);
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UDir_telldir(JNIEnv *env, jclass obj,
+  jlong dirp)
+{
+	return telldir((DIR *)(intptr_t)dirp);
+}
diff --git a/jtux_file.c b/jtux_file.c
new file mode 100755
index 0000000..226b6f6
--- /dev/null
+++ b/jtux_file.c
@@ -0,0 +1,850 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+
+#include "defs.h"
+#include <sys/statvfs.h>
+#include <sys/ioctl.h>
+#include <poll.h>
+#include <sys/uio.h>
+#include <utime.h>
+#include "JtuxFile.h" // generated by javah
+#include "JtuxFile$fd_set.h" // generated by javah
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+static bool statbuf_to_java(JNIEnv *env, jobject buf, struct stat *sbuf)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$s_stat");
+	if (!field_ctoj_long(env, cls, "st_dev", buf, sbuf->st_dev))
+		return false;
+	if (!field_ctoj_int(env, cls, "st_ino", buf, sbuf->st_ino))
+		return false;
+	if (!field_ctoj_int(env, cls, "st_mode", buf, sbuf->st_mode))
+		return false;
+	if (!field_ctoj_int(env, cls, "st_nlink", buf, sbuf->st_nlink))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_uid", buf, sbuf->st_uid))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_gid", buf, sbuf->st_gid))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_rdev", buf, sbuf->st_rdev))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_size", buf, sbuf->st_size))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_atime", buf, sbuf->st_atime))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_mtime", buf, sbuf->st_mtime))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_ctime", buf, sbuf->st_ctime))
+		return false;
+	if (!field_ctoj_int(env, cls, "st_blksize", buf, sbuf->st_blksize))
+		return false;
+	if (!field_ctoj_long(env, cls, "st_blocks", buf, sbuf->st_blocks))
+		return false;
+	return true;
+}
+
+static bool statvfsbuf_to_java(JNIEnv *env, jobject buf, struct statvfs *sbuf)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$s_statvfs");
+	if (!field_ctoj_long(env, cls, "f_bsize", buf, sbuf->f_bsize))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_frsize", buf, sbuf->f_frsize))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_blocks", buf, sbuf->f_blocks))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_bfree", buf, sbuf->f_bfree))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_bavail", buf, sbuf->f_bavail))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_files", buf, sbuf->f_files))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_ffree", buf, sbuf->f_ffree))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_favail", buf, sbuf->f_favail))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_fsid", buf, sbuf->f_fsid))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_flag", buf, sbuf->f_flag))
+		return false;
+	if (!field_ctoj_long(env, cls, "f_namemax", buf, sbuf->f_namemax))
+		return false;
+	return true;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_00024fd_1set_GetSize_1fd_1set(JNIEnv *env, jclass obj)
+{
+	return sizeof(fd_set);
+}
+
+static jbyte *get_fd_set(JNIEnv *env, jobject obj, jbyteArray *ba)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$fd_set");
+	jfieldID fid;
+
+	if (cls == NULL || obj == NULL)
+		return NULL;
+	if ((fid = (*env)->GetFieldID(env, cls, "set", "[B")) == NULL)
+		return NULL;
+	if ((*ba = (*env)->GetObjectField(env, obj, fid)) == NULL)
+		return NULL;
+	return (*env)->GetByteArrayElements(env, *ba, NULL);
+}
+
+static void release_fd_set(JNIEnv *env, jbyteArray b, jbyte *p)
+{
+	// Always copy back, even though for FD_ISSET we don't have to
+	if (b != NULL && p != NULL)
+		(*env)->ReleaseByteArrayElements(env, b, p, 0);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_access(JNIEnv *env, jclass obj,
+  jstring path, jint what)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(access(path_c, what))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_chmod(JNIEnv *env, jclass obj,
+  jstring path, jint mode)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(chmod(path_c, mode))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_chown(JNIEnv *env, jclass obj,
+  jstring path, jlong uid, jlong gid)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(chown(path_c, uid, gid))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_close(JNIEnv *env, jclass obj,
+  jint fd)
+{
+	JTHROW_neg1(close(fd))
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_dup(JNIEnv *env, jclass obj,
+  jint fd)
+{
+	int fd2;
+
+	JTHROW_neg1(fd2 = dup(fd))
+	return fd2;
+}
+
+JNIEXPORT int JNICALL Java_jtux_UFile_dup2(JNIEnv *env, jclass obj, jint fd, jint fd2)
+{
+	JTHROW_neg1(dup2(fd, fd2))
+	return fd2;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_fchmod(JNIEnv *env, jclass obj,
+  jint fd, jint mode)
+{
+	JTHROW_neg1(fchmod(fd, mode))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_fchown(JNIEnv *env, jclass obj,
+  jint fd, jlong uid, jlong gid)
+{
+	JTHROW_neg1(fchown(fd, uid, gid))
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_fcntl(JNIEnv *env, jclass obj,
+  jint fd, jint op, jint arg)
+{
+	int r;
+
+	JTHROW_neg1(r = fcntl(fd, op, arg))
+	return r;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_FD_1CLR(JNIEnv *env, jclass obj,
+  jint fd, jobject set)
+{
+	jbyteArray ba;
+	jbyte *b = get_fd_set(env, set, &ba);
+
+	if (b != NULL) {
+		FD_CLR(fd, (fd_set *)b);
+		release_fd_set(env, ba, b);
+	}
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_FD_1ISSET(JNIEnv *env, jclass obj,
+  jint fd, jobject set)
+{
+	int r;
+	jbyteArray ba;
+	jbyte *b = get_fd_set(env, set, &ba);
+
+	if (b != NULL) {
+		r = FD_ISSET(fd, (fd_set *)b);
+		release_fd_set(env, ba, b);
+		return r != 0;
+	}
+	return false;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_FD_1SET(JNIEnv *env, jclass obj,
+  jint fd, jobject set)
+{
+	jbyteArray ba;
+	jbyte *b = get_fd_set(env, set, &ba);
+
+	if (b != NULL) {
+		FD_SET(fd, (fd_set *)b);
+		release_fd_set(env, ba, b);
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_FD_1ZERO(JNIEnv *env, jclass obj,
+  jobject set)
+{
+	jbyteArray ba;
+	jbyte *b = get_fd_set(env, set, &ba);
+
+	if (b != NULL) {
+		FD_ZERO((fd_set *)b);
+		release_fd_set(env, ba, b);
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_fdatasync(JNIEnv *env, jclass obj,
+  jint fd)
+{
+	JTHROW_neg1(fdatasync(fd))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_fstat(JNIEnv *env, jclass obj,
+  jint fd, jobject buf)
+{
+	struct stat sbuf;
+	int r;
+
+	JTHROW_neg1(r = fstat(fd, &sbuf))
+	if (r == -1)
+		return;
+	if (!statbuf_to_java(env, buf, &sbuf))
+		return;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_fstatvfs(JNIEnv *env, jclass obj,
+  jint fd, jobject buf)
+{
+	struct statvfs sbuf;
+	int r;
+
+	JTHROW_neg1(r = fstatvfs(fd, &sbuf))
+	if (r == -1)
+		return;
+	if (!statvfsbuf_to_java(env, buf, &sbuf))
+		return;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_fsync(JNIEnv *env, jclass obj,
+  jint fd)
+{
+	JTHROW_neg1(fsync(fd))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_ftruncate(JNIEnv *env, jclass obj,
+  jint fd, jlong length)
+{
+	JTHROW_neg1(ftruncate(fd, length))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_lchown(JNIEnv *env, jclass obj,
+  jstring path, jlong uid, jlong gid)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(lchown(path_c, uid, gid))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_link(JNIEnv *env, jclass obj,
+  jstring oldpath, jstring newpath)
+{
+	JSTR_GET_DECL(oldpath_c, oldpath)
+	JSTR_GET_DECL(newpath_c, newpath)
+
+	JSTR_NULLTEST(oldpath_c)
+	JSTR_NULLTEST(newpath_c)
+	JTHROW_neg1(link(oldpath_c, newpath_c))
+	JSTR_REL(oldpath_c, oldpath)
+	JSTR_REL(newpath_c, newpath)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_lockf(JNIEnv *env, jclass obj,
+  jint fd, jint op, jlong len)
+{
+	JTHROW_neg1(lockf(fd, op, len))
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UFile_lseek(JNIEnv *env, jclass obj,
+  jint fd, jlong pos, jint whence)
+{
+	off_t off;
+
+	JTHROW_neg1(off = lseek(fd, pos, whence))
+	return off;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_lstat(JNIEnv *env, jclass obj,
+  jstring path, jobject buf)
+{
+	JSTR_GET_DECL(path_c, path)
+	struct stat sbuf;
+	int r;
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(r = lstat(path_c, &sbuf))
+	JSTR_REL(path_c, path)
+	if (r == -1)
+		return;
+	if (!statbuf_to_java(env, buf, &sbuf))
+		return;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_mkfifo(JNIEnv *env, jclass obj,
+  jstring path, jint perms)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(mkfifo(path_c, perms))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_mknod(JNIEnv *env, jclass obj,
+  jstring path, jint mode, jlong dev)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(mknod(path_c, mode, dev))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_mkstemp(JNIEnv *env, jclass obj,
+  jobject template)
+{
+	jstring obj_string;
+	const char *t = string_buffer_get(env, template, &obj_string);
+	char *templ;
+	int fd = -1;
+
+	if (t != NULL) {
+		JTHROW_null(templ = malloc(strlen(t) + 1))
+		if (templ != NULL) {
+			strcpy(templ, t);
+			JTHROW_neg1(fd = mkstemp(templ))
+			(void)string_buffer_set(env, template, templ);
+			free(templ);
+		}
+		string_buffer_release(env, obj_string, t);
+	}
+	return fd;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_open(JNIEnv *env, jclass obj,
+  jstring path, jint mode, jint perms)
+{
+	int fd;
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST_V(path_c, -1)
+	JTHROW_neg1(fd = open(path_c, mode, perms))
+	JSTR_REL(path_c, path)
+	return fd;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_pipe(JNIEnv *env, jclass obj, jintArray pfd)
+{
+	int fd[2];
+	jint *a;
+
+	JTHROW_neg1(pipe(fd))
+	a = (*env)->GetIntArrayElements(env, pfd, NULL);
+	if (a == NULL)
+		return;
+	a[0] = fd[0];
+	a[1] = fd[1];
+	(*env)->ReleaseIntArrayElements(env, pfd, a, 0);
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_poll(JNIEnv *env, jclass obj,
+  jobjectArray fdinfo, jint nfds, jint timeout)
+{
+	struct pollfd *fi;
+	int i, r;
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$s_pollfd");
+
+	JTHROW_null(fi = malloc(nfds * sizeof(struct pollfd)))
+	if (fi == NULL)
+		return -1;
+	for (i = 0; i < nfds; i++) {
+		jobject fi_obj = (*env)->GetObjectArrayElement(env, fdinfo, i);
+
+		if (fi_obj == NULL) {
+			free(fi);
+			return -1;
+		}
+		if (!field_jtoc_int(env, cls, "fd", fi_obj, &fi[i].fd))
+			return -1;
+		if (!field_jtoc_short(env, cls, "events", fi_obj, &fi[i].events))
+			return -1;
+		if (!field_jtoc_short(env, cls, "revents", fi_obj, &fi[i].revents))
+			return -1;
+	}
+	JTHROW_neg1(r = poll(fi, nfds, timeout))
+	if (r == -1) {
+		free(fi);
+		return -1;
+	}
+	for (i = 0; i < nfds; i++) {
+		jobject fi_obj = (*env)->GetObjectArrayElement(env, fdinfo, i);
+
+		if (fi_obj == NULL) {
+			free(fi);
+			return -1;
+		}
+		if (!field_ctoj_int(env, cls, "fd", fi_obj, fi[i].fd))
+			return -1;
+		if (!field_ctoj_short(env, cls, "events", fi_obj, fi[i].events))
+			return -1;
+		if (!field_ctoj_short(env, cls, "revents", fi_obj, fi[i].revents))
+			return -1;
+	}
+	free(fi);
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_pread(JNIEnv *env, jclass obj,
+  jint fd, jbyteArray buf, jint nbytes, jlong offset)
+{
+	void *buf_c;
+	ssize_t r;
+
+	if ((buf_c = (*env)->GetByteArrayElements(env, buf, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(r = pread(fd, buf_c, nbytes, offset))
+	(*env)->ReleaseByteArrayElements(env, buf, buf_c, 0);
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_pselect(JNIEnv *env, jclass obj,
+  jint nfds, jobject readset, jobject writeset, jobject errorset, jobject timeout,
+  jobject sigmask)
+{
+#if _XOPEN_VERSION >= 600
+// Following compiled but not tested
+	jbyteArray ba_read, ba_write, ba_error, ba_sigmask;
+	jbyte *b_read = get_fd_set(env, readset, &ba_read);
+	jbyte *b_write = get_fd_set(env, writeset, &ba_write);
+	jbyte *b_error = get_fd_set(env, errorset, &ba_error);
+	jbyte *b_sigmask = get_sigset(env, sigmask, &ba_sigmask);
+	jclass cls = (*env)->FindClass(env, "jtux/UProcess$s_timespec");
+	int r;
+	long n;
+	struct timespec tsbuf, *ts = &tsbuf;
+
+	if (timeout == NULL)
+		ts = NULL;
+	else {
+		if (!field_jtoc_long(env, cls, "tv_sec", timeout, &n))
+			return false;
+		ts->tv_sec = (time_t)n;
+		if (!field_jtoc_long(env, cls, "tv_nsec", timeout, &ts->tv_nsec))
+			return false;
+		printf("%ld %ld\n", (long)ts->tv_sec, (long)ts->tv_nsec);
+	}
+	JTHROW_neg1(r = pselect(nfds, (fd_set *)b_read, (fd_set *)b_write,
+	  (fd_set *)b_error, ts, (sigset_t *)b_sigmask))
+	release_fd_set(env, ba_read, b_read);
+	release_fd_set(env, ba_write, b_write);
+	release_fd_set(env, ba_error, b_error);
+	release_sigset(env, ba_sigmask, b_sigmask);
+	return r;
+#else
+	(void)setup_throw_errno(env, ENOSYS);
+	return -1;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_pwrite(JNIEnv *env, jclass obj,
+  jint fd, jbyteArray buf, jint nbytes, jlong offset)
+{
+	void *buf_c;
+	ssize_t r;
+
+	if ((buf_c = (*env)->GetByteArrayElements(env, buf, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(r = pwrite(fd, buf_c, nbytes, offset))
+	(*env)->ReleaseByteArrayElements(env, buf, buf_c, JNI_ABORT);
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_read(JNIEnv *env, jclass obj,
+  jint fd, jbyteArray buf, jint nbytes)
+{
+	void *buf_c;
+	ssize_t r;
+
+	if ((buf_c = (*env)->GetByteArrayElements(env, buf, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(r = read(fd, buf_c, nbytes))
+	(*env)->ReleaseByteArrayElements(env, buf, buf_c, 0);
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_readlink(JNIEnv *env, jclass obj,
+  jstring path, jbyteArray buf, jint bufsize)
+{
+	JSTR_GET_DECL(path_c, path)
+	void *buf_c;
+	ssize_t r;
+
+	JSTR_NULLTEST_V(path_c, -1)
+	if ((buf_c = (*env)->GetByteArrayElements(env, buf, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(r = readlink(path_c, buf_c, bufsize))
+	(*env)->ReleaseByteArrayElements(env, buf, buf_c, 0);
+	JSTR_REL(path_c, path)
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_readv(JNIEnv *env, jclass obj,
+  jint fd, jobjectArray iov, jint iovcnt)
+{
+	struct iovec *v;
+	jbyteArray *v_bytearray;
+	ssize_t r;
+
+	if ((v = iovec_jtoc(env, iov, iovcnt, &v_bytearray)) == NULL)
+		return -1;
+	JTHROW_neg1(r = readv(fd, v, iovcnt))
+	iovec_jtoc_release(env, v, iovcnt, v_bytearray);
+	return r;
+
+#if 0
+	struct iovec *v;
+	jbyteArray *v_bytearray;
+	int i;
+	ssize_t r;
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$s_iovec");
+
+	JTHROW_null(v = malloc(iovcnt * sizeof(struct iovec)))
+	JTHROW_null(v_bytearray = malloc(iovcnt * sizeof(jbyteArray)))
+	if (v == NULL || v_bytearray == NULL)
+		return -1;
+	for (i = 0; i < iovcnt; i++) {
+		jobject v_obj = (*env)->GetObjectArrayElement(env, iov, i);
+
+		if (v_obj == NULL) {
+			free(v);
+			free(v_bytearray);
+			return -1;
+		}
+		if (!field_jtoc_bytearray(env, cls, "iov_base", v_obj, &v[i].iov_base,
+		  &v_bytearray[i]))
+			return -1;
+		if (!field_jtoc_int(env, cls, "iov_len", v_obj, &v[i].iov_len))
+			return -1;
+	}
+	JTHROW_neg1(r = readv(fd, v, iovcnt))
+	for (i = 0; i < iovcnt; i++)
+		field_jtoc_bytearray_release(env, v_bytearray[i], v[i].iov_base);
+	free(v);
+	free(v_bytearray);
+	return r;
+#endif
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_rename(JNIEnv *env, jclass obj,
+  jstring oldpath, jstring newpath)
+{
+	JSTR_GET_DECL(oldpath_c, oldpath)
+	JSTR_GET_DECL(newpath_c, newpath)
+
+	JSTR_NULLTEST(oldpath_c)
+	JSTR_NULLTEST(newpath_c)
+	JTHROW_neg1(rename(oldpath_c, newpath_c))
+	JSTR_REL(oldpath_c, oldpath)
+	JSTR_REL(newpath_c, newpath)
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISBLK(JNIEnv *env, jclass obj,
+  jint m)
+{
+	return S_ISBLK(m);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISCHR(JNIEnv *env, jclass obj,
+  jint m)
+{
+	return S_ISCHR(m);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISDIR(JNIEnv *env, jclass obj,
+  jint m)
+{
+	return S_ISDIR(m);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISFIFO(JNIEnv *env, jclass obj,
+  jint m)
+{
+	return S_ISFIFO(m);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISLNK(JNIEnv *env, jclass obj,
+  jint m)
+{
+	return S_ISLNK(m);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISREG(JNIEnv *env, jclass obj,
+  jint m)
+{
+	return S_ISREG(m);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UFile_S_1ISSOCK(JNIEnv *env, jclass obj,
+  jint m)
+{
+	return S_ISSOCK(m);
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_select(JNIEnv *env, jclass obj,
+  jint nfds, jobject readset, jobject writeset, jobject errorset, jobject timeout)
+{
+	jbyteArray ba_read, ba_write, ba_error;
+	jbyte *b_read = get_fd_set(env, readset, &ba_read);
+	jbyte *b_write = get_fd_set(env, writeset, &ba_write);
+	jbyte *b_error = get_fd_set(env, errorset, &ba_error);
+	jclass cls = (*env)->FindClass(env, "jtux/UProcess$s_timeval");
+	int r;
+	long n;
+	struct timeval tvbuf, *tv = &tvbuf;
+
+	if (timeout == NULL)
+		tv = NULL;
+	else {
+		if (!field_jtoc_long(env, cls, "tv_sec", timeout, &n))
+			return false;
+		tv->tv_sec = (time_t)n;
+		if (!field_jtoc_long(env, cls, "tv_usec", timeout, &n))
+			return false;
+		tv->tv_usec = (suseconds_t)n;
+		printf("%ld %ld\n", (long)tv->tv_sec, (long)tv->tv_usec);
+	}
+	JTHROW_neg1(r = select(nfds, (fd_set *)b_read, (fd_set *)b_write, (fd_set *)b_error, tv))
+	release_fd_set(env, ba_read, b_read);
+	release_fd_set(env, ba_write, b_write);
+	release_fd_set(env, ba_error, b_error);
+	return r;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_stat(JNIEnv *env, jclass obj,
+  jstring path, jobject buf)
+{
+	JSTR_GET_DECL(path_c, path)
+	struct stat sbuf;
+	int r;
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(r = stat(path_c, &sbuf))
+	JSTR_REL(path_c, path)
+	if (r == -1)
+		return;
+	if (!statbuf_to_java(env, buf, &sbuf))
+		return;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_statvfs(JNIEnv *env, jclass obj,
+  jstring path, jobject buf)
+{
+	JSTR_GET_DECL(path_c, path)
+	struct statvfs sbuf;
+	int r;
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(r = statvfs(path_c, &sbuf))
+	JSTR_REL(path_c, path)
+	if (r == -1)
+		return;
+	if (!statvfsbuf_to_java(env, buf, &sbuf))
+		return;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_symlink(JNIEnv *env, jclass obj,
+  jstring oldpath, jstring newpath)
+{
+	JSTR_GET_DECL(oldpath_c, oldpath)
+	JSTR_GET_DECL(newpath_c, newpath)
+
+	JSTR_NULLTEST(oldpath_c)
+	JSTR_NULLTEST(newpath_c)
+	JTHROW_neg1(symlink(oldpath_c, newpath_c))
+	JSTR_REL(oldpath_c, oldpath)
+	JSTR_REL(newpath_c, newpath)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_sync(JNIEnv *env, jclass obj)
+{
+	sync();
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_truncate(JNIEnv *env, jclass obj,
+  jstring path, jlong length)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(truncate(path_c, length))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_unlink(JNIEnv *env, jclass obj,
+  jstring path)
+{
+	JSTR_GET_DECL(path_c, path)
+
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(unlink(path_c))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UFile_utime(JNIEnv *env, jclass obj,
+  jstring path, jobject timbuf)
+{
+	JSTR_GET_DECL(path_c, path)
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$s_utimbuf");
+	struct utimbuf tbuf, *t_c = &tbuf;
+
+	if (timbuf == NULL)
+		t_c = NULL;
+	else {
+		if (!field_jtoc_long(env, cls, "actime", timbuf, &t_c->actime))
+			return;
+		if (!field_jtoc_long(env, cls, "modtime", timbuf, &t_c->modtime))
+			return;
+	}
+	JSTR_NULLTEST(path_c)
+	JTHROW_neg1(utime(path_c, t_c))
+	JSTR_REL(path_c, path)
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_write(JNIEnv *env, jclass obj,
+  jint fd, jbyteArray buf, jint nbytes)
+{
+	void *buf_c;
+	ssize_t r;
+
+	if ((buf_c = (*env)->GetByteArrayElements(env, buf, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(r = write(fd, buf_c, nbytes))
+	(*env)->ReleaseByteArrayElements(env, buf, buf_c, JNI_ABORT);
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_ioctl(JNIEnv *env, jclass obj,
+  jint fd, jint request, jbyteArray buf)
+{
+	void *buf_c;
+	ssize_t r;
+
+	if ((buf_c = (*env)->GetByteArrayElements(env, buf, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(r = ioctl(fd, request, buf_c))
+	(*env)->ReleaseByteArrayElements(env, buf, buf_c, 0);
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_ioctl2(JNIEnv *env, jclass obj,
+  jint fd, jint request, jint arg)
+{
+	jint r;
+
+	r = ioctl(fd, request, arg);
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UFile_writev(JNIEnv *env, jclass obj,
+  jint fd, jobjectArray iov, jint iovcnt)
+{
+	struct iovec *v;
+	jbyteArray *v_bytearray;
+	ssize_t r;
+
+	if ((v = iovec_jtoc(env, iov, iovcnt, &v_bytearray)) == NULL)
+		return -1;
+	JTHROW_neg1(r = writev(fd, v, iovcnt))
+	iovec_jtoc_release_nocopy(env, v, iovcnt, v_bytearray);
+	return r;
+#if 0
+
+
+struct iovec *;
+
+
+
+
+	int i;
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$s_iovec");
+
+	JTHROW_null(v = malloc(iovcnt * sizeof(struct iovec)))
+	JTHROW_null(v_bytearray = malloc(iovcnt * sizeof(jbyteArray)))
+	if (v == NULL || v_bytearray == NULL)
+		return -1;
+	for (i = 0; i < iovcnt; i++) {
+		jobject v_obj = (*env)->GetObjectArrayElement(env, iov, i);
+
+		if (v_obj == NULL) {
+			free(v);
+			free(v_bytearray);
+			return -1;
+		}
+		if (!field_jtoc_bytearray(env, cls, "iov_base", v_obj, &v[i].iov_base,
+		  &v_bytearray[i]))
+			return -1;
+		if (!field_jtoc_int(env, cls, "iov_len", v_obj, &v[i].iov_len))
+			return -1;
+	}
+	JTHROW_neg1(r = writev(fd, v, iovcnt))
+	for (i = 0; i < iovcnt; i++)
+		field_jtoc_bytearray_release_nocopy(env, v_bytearray[i], v[i].iov_base);
+	free(v);
+	free(v_bytearray);
+	return r;
+#endif
+}
diff --git a/jtux_network.c b/jtux_network.c
new file mode 100755
index 0000000..d1980b7
--- /dev/null
+++ b/jtux_network.c
@@ -0,0 +1,732 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+
+#include "defs.h"
+#define __EXTENSIONS__
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include "JtuxNetwork.h" // generated by javah
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+static bool sockaddr_jtoc(JNIEnv *env, jobject sa, struct sockaddr *sa_c,
+  socklen_t *sa_len_c)
+{
+	jclass cls_s_sockaddr_un = (*env)->FindClass(env, "jtux/UNetwork$s_sockaddr_un");
+	jclass cls_s_sockaddr_in = (*env)->FindClass(env, "jtux/UNetwork$s_sockaddr_in");
+	jclass cls_s_sockaddr_in6 = (*env)->FindClass(env, "jtux/UNetwork$s_sockaddr_in6");
+	jclass cls_s_in_addr = (*env)->FindClass(env, "jtux/UNetwork$s_in_addr");
+	jclass cls_s_in6_addr = (*env)->FindClass(env, "jtux/UNetwork$s_in6_addr");
+
+	if (cls_s_sockaddr_un == NULL || cls_s_sockaddr_in == NULL ||
+	  cls_s_sockaddr_in6 == NULL || cls_s_in_addr == NULL || cls_s_in6_addr == NULL)
+		return false;
+	if ((*env)->IsInstanceOf(env, sa, cls_s_sockaddr_un)) {
+		struct sockaddr_un *sp = (struct sockaddr_un *)sa_c;
+		int n;
+
+		if (!field_jtoc_int(env, cls_s_sockaddr_un, "sun_family", sa, &n))
+			return false;
+		sp->sun_family = n;
+		if (!field_jtoc_string(env, cls_s_sockaddr_un, "sun_path", sa, sp->sun_path, sizeof(sp->sun_path)))
+			return false;
+		if (sa_len_c != NULL)
+			*sa_len_c = sizeof(*sp);
+	}
+	else if ((*env)->IsInstanceOf(env, sa, cls_s_sockaddr_in)) {
+		struct sockaddr_in *sp = (struct sockaddr_in *)sa_c;
+		jobject addr;
+		int n;
+		if (!field_jtoc_int(env, cls_s_sockaddr_in, "sin_family", sa, &n))
+			return false;
+		sp->sin_family = n;
+		if (!field_jtoc_short(env, cls_s_sockaddr_in, "sin_port", sa, &sp->sin_port))
+			return false;
+		if (!field_jtoc_object(env, cls_s_sockaddr_in, "sin_addr", "Ljtux/UNetwork$s_in_addr;",
+		  sa, &addr))
+			return false;
+		if (!field_jtoc_int(env, cls_s_in_addr, "s_addr", addr, &sp->sin_addr.s_addr))
+			return false;
+		if (sa_len_c != NULL)
+			*sa_len_c = sizeof(*sp);
+	}
+	else if ((*env)->IsInstanceOf(env, sa, cls_s_sockaddr_in6)) {
+		// Following compiled but not tested.
+		struct sockaddr_in6 *sp = (struct sockaddr_in6 *)sa_c;
+		jobject addr;
+		jbyteArray ba;
+		char *bytes;
+		int n;
+
+		if (!field_jtoc_int(env, cls_s_sockaddr_in6, "sin6_family", sa, &n))
+			return false;
+		sp->sin6_family = n;
+		if (!field_jtoc_short(env, cls_s_sockaddr_in6, "sin6_port", sa, &sp->sin6_port))
+			return false;
+		if (!field_jtoc_int(env, cls_s_sockaddr_in6, "sin6_flowinfo", sa, &sp->sin6_flowinfo))
+			return false;
+		if (!field_jtoc_object(env, cls_s_sockaddr_in6, "sin_addr", "Ljtux/UNetwork$s_in6_addr;",
+		  sa, &addr))
+			return false;
+
+
+		if (!field_jtoc_bytearray(env, cls_s_in6_addr, "s6_addr", addr, (void **)&bytes,
+		  &ba))
+			return false;
+		memcpy(sp->sin6_addr.s6_addr, bytes, 16);
+		field_jtoc_bytearray_release_nocopy(env, ba, bytes);
+		if (!field_jtoc_int(env, cls_s_sockaddr_in6, "sin6_scope_id", sa, &sp->sin6_scope_id))
+			return false;
+		if (sa_len_c != NULL)
+			*sa_len_c = sizeof(*sp);
+	}
+	else
+		setup_throw_errno(env, EINVAL);
+	return true;
+}
+
+/*
+	Creates new object if *sa is NULL going in.
+*/
+static bool sockaddr_ctoj(JNIEnv *env, jobject *sa, struct sockaddr *sa_c)
+{
+	jclass cls_s_sockaddr_in = (*env)->FindClass(env, "jtux/UNetwork$s_sockaddr_in");
+	jclass cls_s_sockaddr_in6 = (*env)->FindClass(env, "jtux/UNetwork$s_sockaddr_in6");
+	jclass cls_s_in_addr = (*env)->FindClass(env, "jtux/UNetwork$s_in_addr");
+	jclass cls_s_in6_addr = (*env)->FindClass(env, "jtux/UNetwork$s_in6_addr");
+
+	if (cls_s_sockaddr_in == NULL || cls_s_sockaddr_in6 == NULL ||
+	  cls_s_in_addr == NULL || cls_s_in6_addr == NULL)
+		return false;
+	switch (sa_c->sa_family) {
+	case AF_INET: {
+		struct sockaddr_in *saddr = (struct sockaddr_in *)sa_c;
+		jobject addrobj;
+		jmethodID mid;
+
+		if (*sa == NULL) {
+			if ((mid = (*env)->GetMethodID(env, cls_s_sockaddr_in, "<init>", "()V")) == NULL)
+				return false;
+			if ((*sa = (*env)->NewObject(env, cls_s_sockaddr_in, mid)) == NULL)
+				return false;
+		}
+		if (!field_ctoj_int(env, cls_s_sockaddr_in, "sin_family", *sa, saddr->sin_family))
+			return false;
+		if (!field_ctoj_short(env, cls_s_sockaddr_in, "sin_port", *sa, saddr->sin_port))
+			return false;
+		if ((mid = (*env)->GetMethodID(env, cls_s_in_addr, "<init>", "()V")) == NULL)
+			return false;
+		if ((addrobj = (*env)->NewObject(env, cls_s_in_addr, mid)) == NULL)
+			return false;
+		if (!field_ctoj_int(env, cls_s_in_addr, "s_addr", addrobj, saddr->sin_addr.s_addr))
+			return false;
+		if (!field_ctoj_object(env, cls_s_sockaddr_in, "sin_addr", "Ljtux/UNetwork$s_in_addr;", *sa, addrobj))
+			return false;
+	}
+		break;
+	case AF_INET6: {
+		// Following compiled but not tested.
+		struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)sa_c;
+		jobject addrobj;
+		jmethodID mid;
+		jbyteArray ba;
+		jbyte *ba_c;
+
+		if (*sa == NULL) {
+			if ((mid = (*env)->GetMethodID(env, cls_s_sockaddr_in6, "<init>", "()V")) == NULL)
+				return false;
+			if ((*sa = (*env)->NewObject(env, cls_s_sockaddr_in6, mid)) == NULL)
+				return false;
+		}
+		if (!field_ctoj_int(env, cls_s_sockaddr_in6, "sin6_family", *sa, saddr->sin6_family))
+			return false;
+		if (!field_ctoj_short(env, cls_s_sockaddr_in6, "sin6_port", *sa, saddr->sin6_port))
+			return false;
+		if (!field_ctoj_int(env, cls_s_sockaddr_in6, "sin6_flowinfo", *sa, saddr->sin6_flowinfo))
+			return false;
+		if ((mid = (*env)->GetMethodID(env, cls_s_in6_addr, "<init>", "()V")) == NULL)
+			return false;
+		if ((addrobj = (*env)->NewObject(env, cls_s_in6_addr, mid)) == NULL)
+			return false;
+		// allocate a 16-byte array and put it into the s6_addr field
+		if ((ba = (*env)->NewByteArray(env, 16)) == NULL)
+			return false;
+		if ((ba_c = (*env)->GetByteArrayElements(env, ba, NULL)) == NULL)
+			return false;
+		memcpy(ba_c, saddr->sin6_addr.s6_addr, 16);
+		(*env)->ReleaseByteArrayElements(env, ba, ba_c, 0);
+		if (!field_ctoj_object(env, cls_s_sockaddr_in6, "sin6_addr", "Ljtux/UNetwork$s_in6_addr;",
+		  *sa, addrobj))
+			return false;
+		// Following needs full 32-bit C int
+		if (!field_ctoj_int(env, cls_s_sockaddr_in6, "sin6_scope_id", *sa, saddr->sin6_scope_id))
+			return false;
+	}
+		break;
+	default:
+		return false; // ??? can't deal with it
+	}
+	return true;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_accept(JNIEnv *env, jclass obj,
+  jint socket_fd, jobject sa, jobject sa_len)
+{
+	int fd;
+	struct sockaddr_storage sa_c;
+	socklen_t sa_len_c;
+
+	JTHROW_neg1(fd = accept(socket_fd, (struct sockaddr *)&sa_c, &sa_len_c))
+	if (fd != -1) {
+		if (!sockaddr_ctoj(env, &sa, (struct sockaddr *)&sa_c))
+			return -1;
+		if (!set_IntHolder_int(env, sa_len, sa_len_c))
+			return -1;
+	}
+	return fd;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_bind(JNIEnv *env, jclass obj,
+  jint socket_fd, jobject sa, jint sa_len)
+{
+	struct sockaddr_storage sa_c;
+	socklen_t sa_len_c;
+
+	if (!sockaddr_jtoc(env, sa, (struct sockaddr *)&sa_c, &sa_len_c))
+		return;
+	JTHROW_neg1(bind(socket_fd, (struct sockaddr *)&sa_c, sa_len_c))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_connect(JNIEnv *env, jclass obj,
+  jint socket_fd, jobject sa, jint sa_len)
+{
+	struct sockaddr_storage sa_c;
+	socklen_t sa_len_c;
+
+	if (!sockaddr_jtoc(env, sa, (struct sockaddr *)&sa_c, &sa_len_c))
+		return;
+	JTHROW_neg1(connect(socket_fd, (struct sockaddr *)&sa_c, sa_len_c))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_freeaddrinfo(JNIEnv *env, jclass obj,
+  jobject infop)
+{
+	// no-op -- getaddrinfo has already freed the C linked list
+}
+
+JNIEXPORT jstring JNICALL Java_jtux_UNetwork_gai_1strerror(JNIEnv *env, jclass obj,
+  jint code)
+{
+	JSTR_RETURN(gai_strerror(code));
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_getaddrinfo(JNIEnv *env, jclass obj,
+  jstring nodename, jstring servname, jobject hint, jobject infop)
+{
+	const char *nodename_c, *servname_c;
+	struct addrinfo hint_buf, *hint_c = &hint_buf, *infop_c;
+	jclass cls_s_addrinfo = (*env)->FindClass(env, "jtux/UNetwork$s_addrinfo");
+	jclass cls_AddrInfoListHead = (*env)->FindClass(env, "jtux/UNetwork$AddrInfoListHead");
+	jclass cls_s_sockaddr_in = (*env)->FindClass(env, "jtux/UNetwork$s_sockaddr_in");
+	jclass cls_s_sockaddr_in6 = (*env)->FindClass(env, "jtux/UNetwork$s_sockaddr_in6");
+	jclass cls_s_in_addr = (*env)->FindClass(env, "jtux/UNetwork$s_in_addr");
+	jclass cls_s_in6_addr = (*env)->FindClass(env, "jtux/UNetwork$s_in6_addr");
+	int r;
+
+	if (cls_s_addrinfo == NULL || cls_AddrInfoListHead == NULL ||
+	  cls_s_sockaddr_in == NULL || cls_s_sockaddr_in6 == NULL ||
+	  cls_s_in_addr == NULL || cls_s_in6_addr == NULL)
+		return;
+	if (hint == NULL)
+		hint_c = NULL;
+	else {
+		memset(hint_c, 0, sizeof(struct addrinfo));
+		if (!field_jtoc_int(env, cls_s_addrinfo, "ai_flags", hint, &hint_c->ai_flags))
+			return;
+		if (!field_jtoc_int(env, cls_s_addrinfo, "ai_family", hint, &hint_c->ai_family))
+			return;
+		if (!field_jtoc_int(env, cls_s_addrinfo, "ai_socktype", hint, &hint_c->ai_socktype))
+			return;
+		if (!field_jtoc_int(env, cls_s_addrinfo, "ai_protocol", hint, &hint_c->ai_protocol))
+			return;
+	}
+	nodename_c = (*env)->GetStringUTFChars(env, nodename, NULL);
+	servname_c = (*env)->GetStringUTFChars(env, servname, NULL);
+	JSTR_NULLTEST(nodename_c)
+	JSTR_NULLTEST(servname_c)
+	if ((r = getaddrinfo(nodename_c, servname_c, hint_c, &infop_c)) > 0)
+		setup_throw_errno_type(env, r, EC_EAI);
+	JSTR_REL(nodename_c, nodename)
+	JSTR_REL(servname_c, servname)
+	if (r == 0) {
+		struct addrinfo *p;
+		jobject prev_node = infop;
+		jobject node;
+		for (p = infop_c; p != NULL; p = p->ai_next, prev_node = node) {
+			jmethodID mid = (*env)->GetMethodID(env, cls_s_addrinfo, "<init>", "()V");
+			jclass cls;
+			jobject saobj = NULL;
+
+			if (mid == NULL)
+				break;
+			if ((node = (*env)->NewObject(env, cls_s_addrinfo, mid)) == NULL)
+				break;
+			if (p == infop_c)
+				cls = cls_AddrInfoListHead;
+			else
+				cls = cls_s_addrinfo;
+			if (!field_ctoj_object(env, cls, "ai_next", "Ljtux/UNetwork$s_addrinfo;",
+			  prev_node, node))
+				break;
+			if (!field_ctoj_int(env, cls_s_addrinfo, "ai_flags", node, p->ai_flags))
+				break;
+			if (!field_ctoj_int(env, cls_s_addrinfo, "ai_family", node, p->ai_family))
+				break;
+			if (!field_ctoj_int(env, cls_s_addrinfo, "ai_socktype", node, p->ai_socktype))
+				break;
+			if (!field_ctoj_int(env, cls_s_addrinfo, "ai_protocol", node, p->ai_protocol))
+				break;
+			if (!field_ctoj_int(env, cls_s_addrinfo, "ai_addrlen", node, p->ai_addrlen))
+				break;
+			if (!sockaddr_ctoj(env, &saobj, p->ai_addr))
+				break;
+			if (!field_ctoj_object(env, cls_s_addrinfo, "ai_addr", "Ljtux/UNetwork$s_sockaddr;",
+			  node, saobj))
+				break;
+			if (!field_ctoj_string(env, cls_s_addrinfo, "ai_canonname", node, p->ai_canonname))
+				break;
+		}
+		freeaddrinfo(infop_c);
+	}
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UNetwork_gethostid(JNIEnv *env, jclass obj)
+{
+	return 0;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_gethostname(JNIEnv *env, jclass obj,
+  jobject name)
+{
+	long size = 1000;
+	char *buf;
+
+#ifdef _SC_HOST_NAME_MAX
+	errno = 0;
+	if ((size = sysconf(_SC_HOST_NAME_MAX)) == -1) {
+		if (errno == 0)
+			size = 1000;
+		else {
+			(void)setup_throw_errno(env, errno);
+			return;
+		}
+        }
+#endif
+	JTHROW_null(buf = malloc(size))
+	if (buf != NULL) {
+		JTHROW_neg1(gethostname(buf, size))
+		(void)string_buffer_set(env, name, buf);
+		free(buf);
+	}
+}
+
+/*
+	sa_len not used
+*/
+JNIEXPORT void JNICALL Java_jtux_UNetwork_getnameinfo(JNIEnv *env, jclass obj,
+  jobject sa, jint sa_len, jobject nodename, jobject servname, jint flags)
+{
+	struct sockaddr_storage sa_c;
+	socklen_t sa_len_c;
+	char nodename_c[1000], servname_c[1000];
+	int r;
+
+	if (!sockaddr_jtoc(env, sa, (struct sockaddr *)&sa_c, &sa_len_c))
+		return;
+	if ((r = getnameinfo((struct sockaddr *)&sa_c, sa_len_c, nodename_c,
+	  sizeof(nodename_c), servname_c, sizeof(servname_c), flags)) > 0)
+		setup_throw_errno_type(env, r, EC_EAI);
+	if (nodename != NULL)
+		if (!string_buffer_set(env, nodename, nodename_c))
+			return;
+	if (servname != NULL)
+		if (!string_buffer_set(env, servname, servname_c))
+			return;
+}
+
+// value_len may not be needed
+/*
+	Burden is on Java caller to supply correct object for value.
+*/
+JNIEXPORT void JNICALL Java_jtux_UNetwork_getsockopt(JNIEnv *env, jclass obj,
+  jint socket_fd, jint level, jint option, jobject value, jobject value_len)
+{
+	jclass cls_SockOptValue_int = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_int");
+	jclass cls_SockOptValue_boolean = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_boolean");
+	jclass cls_SockOptValue_s_linger = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_s_linger");
+	jclass cls_s_linger = (*env)->FindClass(env, "jtux/UNetwork$s_linger");
+	jclass cls_SockOptValue_s_timeval = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_s_timeval");
+	jclass cls_s_timeval = (*env)->FindClass(env, "jtux/UProcess$s_timeval");
+	union {
+		int value_int;
+		int value_boolean;
+		struct linger value_linger;
+		struct timeval value_timeval;
+	} all_in_one, *value_c = &all_in_one;
+	socklen_t value_len_c;
+
+	if (cls_SockOptValue_int == NULL || cls_SockOptValue_boolean == NULL ||
+	  cls_SockOptValue_s_linger == NULL || cls_SockOptValue_s_timeval == NULL ||
+	  cls_s_linger == NULL || cls_s_timeval == NULL)
+		return;
+	value_len_c = sizeof(*value_c);
+	JTHROW_neg1(getsockopt(socket_fd, level, option, value_c, &value_len_c))
+	if (!set_IntHolder_int(env, value_len, value_len_c))
+		return;
+	if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_int)) {
+		if (!field_ctoj_int(env, cls_SockOptValue_int, "value", value, value_c->value_int))
+			return;
+	}
+	else if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_boolean)) {
+		if (!field_ctoj_boolean(env, cls_SockOptValue_boolean, "value", value, value_c->value_int))
+			return;
+	}
+	else if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_s_linger)) {
+		jobject linger;
+
+		if (!field_jtoc_object(env, cls_SockOptValue_s_linger, "value", "Ljtux/UNetwork$s_linger;", value, &linger))
+			return;
+		if (!field_ctoj_int(env, cls_s_linger, "l_onoff", linger, value_c->value_linger.l_onoff))
+			return;
+		if (!field_ctoj_int(env, cls_s_linger, "l_linger", linger, value_c->value_linger.l_linger))
+			return;
+	}
+	else if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_s_timeval)) {
+		// timeval case compiled but not tested
+		jobject timeval;
+
+		if (!field_jtoc_object(env, cls_SockOptValue_s_timeval, "value", "Ljtux/UProcess$s_timeval;", value, &timeval))
+			return;
+		if (!field_ctoj_long(env, cls_s_timeval, "tv_sec", timeval, value_c->value_timeval.tv_sec))
+			return;
+		if (!field_ctoj_long(env, cls_s_timeval, "tv_usec", timeval, value_c->value_timeval.tv_usec))
+			return;
+	}
+	else {
+		(void)setup_throw_errno(env, EINVAL);
+		return;
+	}
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_htonl(JNIEnv *env, jclass obj,
+  jint hostnum)
+{
+	return htonl(hostnum);
+}
+
+JNIEXPORT jshort JNICALL Java_jtux_UNetwork_htons(JNIEnv *env, jclass obj,
+  jshort hostnum)
+{
+	return htons(hostnum);
+}
+
+JNIEXPORT jstring JNICALL Java_jtux_UNetwork_inet_1ntop__II(JNIEnv *env, jclass obj,
+  jint domain, jint src)
+{
+	const char *s;
+	uint32_t ipv4 = src;
+	char dst[INET_ADDRSTRLEN];
+
+	JTHROW_null(s = inet_ntop(domain, &ipv4, dst, sizeof(dst)))
+	JSTR_RETURN(s);
+}
+
+JNIEXPORT jstring JNICALL Java_jtux_UNetwork_inet_1ntop__I_3B(JNIEnv *env, jclass obj,
+  jint domain, jbyteArray src)
+{
+	return 0;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_inet_1pton__ILjava_lang_String_2Ljtux_UUtil_00024IntHolder_2(JNIEnv *env, jclass obj,
+  jint domain, jstring src, jobject dst)
+{
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_inet_1pton__ILjava_lang_String_2_3B(JNIEnv *env, jclass obj,
+  jint domain, jstring src, jbyteArray dst)
+{
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_listen(JNIEnv *env, jclass obj,
+  jint socket_fd, jint backlog)
+{
+	JTHROW_neg1(listen(socket_fd, backlog))
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_ntohl(JNIEnv *env, jclass obj,
+  jint netnum)
+{
+	return ntohl(netnum);
+}
+
+JNIEXPORT jshort JNICALL Java_jtux_UNetwork_ntohs(JNIEnv *env, jclass obj,
+  jshort netnum)
+{
+	return ntohs(netnum);
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_recv(JNIEnv *env, jclass obj,
+  jint socket_fd, jbyteArray buffer, jint length, jint flags)
+{
+	void *buffer_c;
+	ssize_t nrcv;
+
+	if ((buffer_c = (*env)->GetByteArrayElements(env, buffer, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(nrcv = recv(socket_fd, buffer_c, length, flags))
+	(*env)->ReleaseByteArrayElements(env, buffer, buffer_c, 0);
+	return nrcv;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_recvfrom(JNIEnv *env, jclass obj,
+  jint socket_fd, jbyteArray buffer, jint length, jint flags, jobject sa, jobject sa_len)
+{
+	struct sockaddr_storage sa_c;
+	socklen_t sa_len_c = sizeof(sa_c);
+	void *buffer_c;
+	ssize_t nrcv;
+
+	if ((buffer_c = (*env)->GetByteArrayElements(env, buffer, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(nrcv = recvfrom(socket_fd, buffer_c, length, flags,
+	  (struct sockaddr *)&sa_c, &sa_len_c))
+	(*env)->ReleaseByteArrayElements(env, buffer, buffer_c, 0);
+	if (nrcv != -1) {
+		if (!set_IntHolder_int(env, sa_len, sa_len_c))
+			return -1;
+		if (!sockaddr_ctoj(env, &sa, (struct sockaddr *)&sa_c))
+			return -1;
+	}
+	return nrcv;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_recvmsg(JNIEnv *env, jclass obj,
+  jint socket_fd, jobject message, jint flags)
+{
+	jclass cls_s_msghdr = (*env)->FindClass(env, "jtux/UNetwork$s_msghdr");
+	struct msghdr msg_c;
+	jobject msg_name, msg_control, msg_iov;
+	struct sockaddr_storage sa_c;
+	ssize_t nrcv;
+	jbyteArray *v_bytearray;
+
+	msg_c.msg_name = &sa_c;
+	if (!field_jtoc_object(env, cls_s_msghdr, "msg_iov", "[Ljtux/UFile$s_iovec;", message, &msg_iov))
+		return -1;
+	if (!field_jtoc_int(env, cls_s_msghdr, "msg_iovlen", message, &msg_c.msg_iovlen))
+		return -1;
+	if (!field_jtoc_object(env, cls_s_msghdr, "msg_control", "[B", message, &msg_control))
+		return -1;
+	if (!field_jtoc_int(env, cls_s_msghdr, "msg_controllen", message, &msg_c.msg_controllen))
+		return -1;
+	if (!field_jtoc_int(env, cls_s_msghdr, "msg_flags", message, &msg_c.msg_flags))
+		return -1;
+	if ((msg_c.msg_iov = iovec_jtoc(env, msg_iov, msg_c.msg_iovlen, &v_bytearray)) == NULL)
+		return -1;
+	if (msg_control == NULL)
+		msg_c.msg_control = NULL;
+	else if ((msg_c.msg_control = (*env)->GetByteArrayElements(env, msg_control, NULL)) == NULL) {
+		iovec_jtoc_release(env, msg_c.msg_iov, msg_c.msg_iovlen, v_bytearray);
+		return -1;
+	}
+	JTHROW_neg1(nrcv = recvmsg(socket_fd, &msg_c, flags))
+	iovec_jtoc_release(env, msg_c.msg_iov, msg_c.msg_iovlen, v_bytearray);
+	if (msg_control != NULL)
+		(*env)->ReleaseByteArrayElements(env, msg_control, msg_c.msg_control, JNI_ABORT);
+	if (!field_jtoc_object(env, cls_s_msghdr, "msg_name", "Ljtux/UNetwork$s_sockaddr;", message, &msg_name))
+		return -1;
+	if (msg_name != NULL)
+		if (!sockaddr_ctoj(env, &msg_name, (struct sockaddr *)&sa_c))
+			return -1;
+	return nrcv;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_send(JNIEnv *env, jclass obj,
+  jint socket_fd, jbyteArray data, jint length, jint flags)
+{
+	void *data_c;
+	ssize_t nsent;
+
+	if ((data_c = (*env)->GetByteArrayElements(env, data, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(nsent = send(socket_fd, data_c, length, flags))
+	(*env)->ReleaseByteArrayElements(env, data, data_c, JNI_ABORT);
+	return nsent;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_sendmsg(JNIEnv *env, jclass obj,
+  jint socket_fd, jobject message, jint flags)
+{
+	jclass cls_s_msghdr = (*env)->FindClass(env, "jtux/UNetwork$s_msghdr");
+	struct msghdr msg_c;
+	jobject msg_name, msg_control, msg_iov;
+	struct sockaddr_storage sa_c;
+	ssize_t nsent;
+	jbyteArray *v_bytearray;
+
+	if (!field_jtoc_object(env, cls_s_msghdr, "msg_name", "Ljtux/UNetwork$s_sockaddr;", message, &msg_name))
+		return -1;
+	if (!sockaddr_jtoc(env, msg_name, (struct sockaddr *)&sa_c, &msg_c.msg_namelen))
+		return -1;
+	msg_c.msg_name = &sa_c;
+	if (!field_jtoc_object(env, cls_s_msghdr, "msg_iov", "[Ljtux/UFile$s_iovec;", message, &msg_iov))
+		return -1;
+	if (!field_jtoc_int(env, cls_s_msghdr, "msg_iovlen", message, &msg_c.msg_iovlen))
+		return -1;
+	if (!field_jtoc_object(env, cls_s_msghdr, "msg_control", "[B", message, &msg_control))
+		return -1;
+	if (!field_jtoc_int(env, cls_s_msghdr, "msg_controllen", message, &msg_c.msg_controllen))
+		return -1;
+	if (!field_jtoc_int(env, cls_s_msghdr, "msg_flags", message, &msg_c.msg_flags))
+		return -1;
+	if ((msg_c.msg_iov = iovec_jtoc(env, msg_iov, msg_c.msg_iovlen, &v_bytearray)) == NULL)
+		return -1;
+	if (msg_control == NULL)
+		msg_c.msg_control = NULL;
+	else if ((msg_c.msg_control = (*env)->GetByteArrayElements(env, msg_control, NULL)) == NULL) {
+		iovec_jtoc_release_nocopy(env, msg_c.msg_iov, msg_c.msg_iovlen, v_bytearray);
+		return -1;
+	}
+	JTHROW_neg1(nsent = sendmsg(socket_fd, &msg_c, flags))
+	iovec_jtoc_release_nocopy(env, msg_c.msg_iov, msg_c.msg_iovlen, v_bytearray);
+	if (msg_control != NULL)
+		(*env)->ReleaseByteArrayElements(env, msg_control, msg_c.msg_control, JNI_ABORT);
+	return nsent;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_sendto(JNIEnv *env, jclass obj,
+  jint socket_fd, jbyteArray message, jint length, jint flags, jobject sa, jint sa_len)
+{
+	struct sockaddr_storage sa_c;
+	socklen_t sa_len_c;
+	void *message_c;
+	ssize_t nsent;
+
+	if (!sockaddr_jtoc(env, sa, (struct sockaddr *)&sa_c, &sa_len_c))
+		return -1;
+	if ((message_c = (*env)->GetByteArrayElements(env, message, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(nsent = sendto(socket_fd, message_c, length, flags,
+	  (struct sockaddr *)&sa_c, sa_len_c))
+	(*env)->ReleaseByteArrayElements(env, message, message_c, JNI_ABORT);
+	return nsent;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UNetwork_setsockopt(JNIEnv *env, jclass obj,
+  jint socket_fd, jint level, jint option, jobject value, jint value_len)
+{
+	jclass cls_SockOptValue_int = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_int");
+	jclass cls_SockOptValue_boolean = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_boolean");
+	jclass cls_SockOptValue_s_linger = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_s_linger");
+	jclass cls_s_linger = (*env)->FindClass(env, "jtux/UNetwork$s_linger");
+	jclass cls_SockOptValue_s_timeval = (*env)->FindClass(env, "jtux/UNetwork$SockOptValue_s_timeval");
+	jclass cls_s_timeval = (*env)->FindClass(env, "jtux/UProcess$s_timeval");
+	void *value_c;
+	int value_int;
+	struct linger value_linger;
+	struct timeval value_timeval;
+
+	if (cls_SockOptValue_int == NULL || cls_SockOptValue_boolean == NULL ||
+	  cls_SockOptValue_s_linger == NULL || cls_SockOptValue_s_timeval == NULL ||
+	  cls_s_linger == NULL || cls_s_timeval == NULL)
+		return;
+	if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_int)) {
+		if (!field_jtoc_int(env, cls_SockOptValue_int, "value", value, &value_int))
+			return;
+		value_c = &value_int;
+		value_len = sizeof(value_int);
+	}
+	else if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_boolean)) {
+		if (!field_jtoc_boolean(env, cls_SockOptValue_boolean, "value", value, &value_int))
+			return;
+		value_c = &value_int;
+		value_len = sizeof(value_int);
+	}
+	else if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_s_linger)) {
+		jobject linger;
+
+		if (!field_jtoc_object(env, cls_SockOptValue_s_linger, "value", "Ljtux/UNetwork$s_linger;", value, &linger))
+			return;
+		if (!field_jtoc_int(env, cls_s_linger, "l_onoff", linger, &value_linger.l_onoff))
+			return;
+		if (!field_jtoc_int(env, cls_s_linger, "l_linger", linger, &value_linger.l_linger))
+			return;
+		value_c = &value_linger;
+		value_len = sizeof(value_linger);
+	}
+	else if ((*env)->IsInstanceOf(env, value, cls_SockOptValue_s_timeval)) {
+		// timeval case compiled but not tested
+		jobject timeval;
+		long n;
+
+		if (!field_jtoc_object(env, cls_SockOptValue_s_timeval, "value", "Ljtux/UProcess$s_timeval;", value, &timeval))
+			return;
+		if (!field_jtoc_long(env, cls_s_timeval, "tv_sec", timeval, &n))
+			return;
+		value_timeval.tv_sec = (time_t)n;
+		if (!field_jtoc_long(env, cls_s_timeval, "tv_usec", timeval, &n))
+			return;
+		value_timeval.tv_usec = (suseconds_t)n;
+		value_c = &value_timeval;
+		value_len = sizeof(value_timeval);
+	}
+	else {
+		(void)setup_throw_errno(env, EINVAL);
+		return;
+	}
+	JTHROW_neg1(setsockopt(socket_fd, level, option, value_c, value_len))
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_sockatmark(JNIEnv *env, jclass obj,
+  jint socket_fd)
+{
+#if _XOPEN_VERSION >= 600
+// Following compiled but not tested
+	int r;
+
+	JTHROW_neg1(r = sockatmark(socket_fd))
+	return r;
+#else
+	(void)setup_throw_errno(env, ENOSYS);
+	return -1;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UNetwork_socket(JNIEnv *env, jclass obj,
+  jint domain, jint type, jint protocol)
+{
+	int fd;
+
+	JTHROW_neg1(fd = socket(domain, type, protocol));
+	return fd;
+}
+
+
diff --git a/jtux_posixipc.c b/jtux_posixipc.c
new file mode 100755
index 0000000..008b570
--- /dev/null
+++ b/jtux_posixipc.c
@@ -0,0 +1,415 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+
+#include "defs.h"
+#include <mqueue.h>
+#include <semaphore.h>
+#include <sys/mman.h>
+#include "JtuxPosixIPC.h" // generated by javah
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_mmap(JNIEnv *env, jclass obj,
+  jlong addr, jint len, jint prot, jint flags, jint fd, jlong off)
+{
+	void *p;
+
+	if ((p = mmap((void *)(intptr_t)addr, len, prot, flags, fd, off)) == MAP_FAILED)
+		JTHROW_null(NULL)
+	return (intptr_t)p;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1close(JNIEnv *env, jclass obj,
+  jlong mqd)
+{
+	JTHROW_neg1(mq_close((mqd_t)(intptr_t)mqd))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1getattr(JNIEnv *env, jclass obj,
+  jlong mqd, jobject attr)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UPosixIPC$s_mq_attr");
+	struct mq_attr attr_c;
+	int r;
+
+	JTHROW_neg1(r = mq_getattr((mqd_t)(intptr_t)mqd, &attr_c))
+	if (r != -1) {
+		if (!field_ctoj_long(env, cls, "mq_flags", attr, attr_c.mq_flags))
+			return;
+		if (!field_ctoj_long(env, cls, "mq_maxmsg", attr, attr_c.mq_maxmsg))
+			return;
+		if (!field_ctoj_long(env, cls, "mq_msgsize", attr, attr_c.mq_msgsize))
+			return;
+		if (!field_ctoj_long(env, cls, "mq_curmsgs", attr, attr_c.mq_curmsgs))
+			return;
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1notify(JNIEnv *env, jclass obj,
+  jlong mqd, jobject ep)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UProcess$s_sigevent");
+	jclass cls_u_sigval_int = (*env)->FindClass(env, "jtux/UProcess$u_sigval_int");
+	jclass cls_u_sigval_ptr = (*env)->FindClass(env, "jtux/UProcess$u_sigval_ptr");
+	jfieldID fid;
+	jobject sigev_value;
+	struct sigevent sigevent_buf, *ep_c = &sigevent_buf;
+	long sival_ptr;
+
+	if (ep == NULL)
+		ep_c = NULL;
+	else {
+		if (!field_jtoc_int(env, cls, "sigev_notify", ep, &ep_c->sigev_notify))
+			return;
+		if (!field_jtoc_int(env, cls, "sigev_signo", ep, &ep_c->sigev_signo))
+			return;
+		if ((fid = (*env)->GetFieldID(env, cls, "sigev_value", "Ljtux/UProcess$u_sigval;")) == NULL)
+			return;
+		if ((sigev_value = (*env)->GetObjectField(env, ep, fid)) == NULL) {
+			JNU_ThrowByName(env, "NullPointerException", "sigev_value field not initialized");
+			return;
+		}
+		if ((*env)->IsInstanceOf(env, sigev_value, cls_u_sigval_int)) {
+			if (!field_jtoc_int(env, cls_u_sigval_int, "sival_int", sigev_value,
+			  &ep_c->sigev_value.sival_int))
+				return;
+		}
+		else if ((*env)->IsInstanceOf(env, sigev_value, cls_u_sigval_ptr)) {
+			if (!field_jtoc_long(env, cls_u_sigval_ptr, "sival_ptr", sigev_value,
+			  &sival_ptr))
+				return;
+			ep_c->sigev_value.sival_ptr = (void *)(intptr_t)sival_ptr;
+		}
+		else {
+			(void)setup_throw_errno(env, EINVAL);
+			return;
+		}
+	}
+	JTHROW_neg1(mq_notify((mqd_t)(intptr_t)mqd, ep_c))
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_mq_1open__Ljava_lang_String_2I(JNIEnv *env, jclass obj,
+  jstring name, jint flags)
+{
+	JSTR_GET_DECL(name_c, name)
+	mqd_t mqd;
+
+	JSTR_NULLTEST_V(name_c, -1)
+	JTHROW_neg1(mqd = mq_open(name_c, flags))
+	JSTR_REL(name_c, name)
+	return (intptr_t)mqd;
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_mq_1open__Ljava_lang_String_2IILjtux_UPosixIPC_00024s_1mq_1attr_2(JNIEnv *env, jclass obj,
+  jstring name, jint flags, jint perms, jobject attr)
+{
+	JSTR_GET_DECL(name_c, name)
+	mqd_t mqd;
+	struct mq_attr attr_c_buf, *attr_c = &attr_c_buf;
+	jclass cls = (*env)->FindClass(env, "jtux/UPosixIPC$s_mq_attr");
+
+	JSTR_NULLTEST_V(name_c, -1)
+	if (attr == NULL)
+		attr_c = NULL;
+	else {
+		if (!field_jtoc_long(env, cls, "mq_flags", attr, &attr_c->mq_flags))
+			return -1;
+		if (!field_jtoc_long(env, cls, "mq_maxmsg", attr, &attr_c->mq_maxmsg))
+			return -1;
+		if (!field_jtoc_long(env, cls, "mq_msgsize", attr, &attr_c->mq_msgsize))
+			return -1;
+		if (!field_jtoc_long(env, cls, "mq_curmsgs", attr, &attr_c->mq_curmsgs))
+			return -1;
+	}
+	JTHROW_neg1(mqd = mq_open(name_c, flags, perms, attr_c))
+	JSTR_REL(name_c, name)
+	return (intptr_t)mqd;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UPosixIPC_mq_1receive(JNIEnv *env, jclass obj,
+  jlong mqd, jbyteArray msg, jint msgsize, jobject priority)
+{
+	ssize_t n;
+	void *msgp_c;
+	int priority_c;
+	jclass cls = (*env)->FindClass(env, "jtux/UUtil$IntHolder");
+
+	if ((msgp_c = (*env)->GetByteArrayElements(env, msg, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(n = mq_receive((mqd_t)(intptr_t)mqd, msgp_c, msgsize, &priority_c))
+	(*env)->ReleaseByteArrayElements(env, msg, msgp_c, 0);
+	if (priority != NULL && n != -1) {
+		if (!field_ctoj_int(env, cls, "value", priority, priority_c))
+			return -1;
+	}
+	return n;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1send(JNIEnv *env, jclass obj,
+  jlong mqd, jbyteArray msg, jint msgsize, jint priority)
+{
+	void *msgp_c;
+
+	if ((msgp_c = (*env)->GetByteArrayElements(env, msg, NULL)) == NULL)
+		return;
+	JTHROW_neg1(mq_send((mqd_t)(intptr_t)mqd, msgp_c, msgsize, priority))
+	(*env)->ReleaseByteArrayElements(env, msg, msgp_c, JNI_ABORT);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1setattr(JNIEnv *env, jclass obj,
+  jlong mqd, jobject attr, jobject oattr)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UPosixIPC$s_mq_attr");
+	struct mq_attr attr_c, oattr_buf, *oattr_c = &oattr_buf;
+	int r;
+
+	if (oattr == NULL)
+		oattr_c = NULL;
+	if (!field_jtoc_long(env, cls, "mq_flags", attr, &attr_c.mq_flags))
+		return;
+	if (!field_jtoc_long(env, cls, "mq_maxmsg", attr, &attr_c.mq_maxmsg))
+		return;
+	if (!field_jtoc_long(env, cls, "mq_msgsize", attr, &attr_c.mq_msgsize))
+		return;
+	if (!field_jtoc_long(env, cls, "mq_curmsgs", attr, &attr_c.mq_curmsgs))
+		return;
+	JTHROW_neg1(r = mq_setattr((mqd_t)(intptr_t)mqd, &attr_c, oattr_c))
+	if (oattr != NULL && r != -1) {
+		if (!field_ctoj_long(env, cls, "mq_flags", oattr, oattr_c->mq_flags))
+			return;
+		if (!field_ctoj_long(env, cls, "mq_maxmsg", oattr, oattr_c->mq_maxmsg))
+			return;
+		if (!field_ctoj_long(env, cls, "mq_msgsize", oattr, oattr_c->mq_msgsize))
+			return;
+		if (!field_ctoj_long(env, cls, "mq_curmsgs", oattr, oattr_c->mq_curmsgs))
+			return;
+	}
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UPosixIPC_mq_1timedreceive(JNIEnv *env, jclass obj,
+  jlong mqd, jbyteArray msg, jint msgsize, jobject priority, jobject tmout)
+{
+#if _XOPEN_VERSION >= 600
+// Following compiled but not tested
+	ssize_t n;
+	void *msgp_c;
+	int priority_c;
+	jclass cls_IntHolder = (*env)->FindClass(env, "jtux/UUtil$IntHolder");
+	jclass cls_timespec = (*env)->FindClass(env, "jtux/UProcess$s_timespec");
+	struct timespec tmout_c;
+	long sec;
+
+	if ((msgp_c = (*env)->GetByteArrayElements(env, msg, NULL)) == NULL)
+		return -1;
+	if (!field_jtoc_long(env, cls_timespec, "tv_sec", tmout, &sec))
+		return -1;
+	tmout_c.tv_sec = (time_t)sec;
+	if (!field_jtoc_long(env, cls_timespec, "tv_nsec", tmout, &tmout_c.tv_nsec))
+		return -1;
+	JTHROW_neg1(n = mq_timedreceive((mqd_t)(intptr_t)mqd, msgp_c, msgsize, &priority_c,
+	  &tmout_c))
+	(*env)->ReleaseByteArrayElements(env, msg, msgp_c, 0);
+	if (priority != NULL && n != -1) {
+		if (!field_ctoj_int(env, cls_IntHolder, "value", priority, priority_c))
+			return -1;
+	}
+	return n;
+#else
+	(void)setup_throw_errno(env, ENOSYS);
+	return -1;
+#endif
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1timedsend(JNIEnv *env, jclass obj,
+  jlong mqd, jbyteArray msg, jint msgsize, jint priority, jobject tmout)
+{
+#if _XOPEN_VERSION >= 600
+// Following compiled but not tested
+	void *msgp_c;
+	jclass cls_timespec = (*env)->FindClass(env, "jtux/UProcess$s_timespec");
+	struct timespec tmout_c;
+	long sec;
+
+	if ((msgp_c = (*env)->GetByteArrayElements(env, msg, NULL)) == NULL)
+		return;
+	if (!field_jtoc_long(env, cls_timespec, "tv_sec", tmout, &sec))
+		return;
+	tmout_c.tv_sec = (time_t)sec;
+	if (!field_jtoc_long(env, cls_timespec, "tv_nsec", tmout, &tmout_c.tv_nsec))
+		return;
+	JTHROW_neg1(mq_timedsend((mqd_t)(intptr_t)mqd, msgp_c, msgsize, priority,
+	  &tmout_c))
+	(*env)->ReleaseByteArrayElements(env, msg, msgp_c, JNI_ABORT);
+#else
+	(void)setup_throw_errno(env, ENOSYS);
+#endif
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_mq_1unlink(JNIEnv *env, jclass obj,
+  jstring name)
+{
+	JSTR_GET_DECL(name_c, name)
+
+	JSTR_NULLTEST(name_c)
+	JTHROW_neg1(mq_unlink(name_c))
+	JSTR_REL(name_c, name)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_munmap(JNIEnv *env, jclass obj,
+   jlong addr, jint len)
+{
+	JTHROW_neg1(munmap((void *)(intptr_t)addr, len))
+}
+
+/* Not needed... yet!
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_sem_1alloc(JNIEnv *env, jclass obj)
+{
+	sem_t *sem;
+
+	JTHROW_null(sem = malloc(sizeof(sem_t)))
+	return (intptr_t)sem;
+}
+*/
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1close(JNIEnv *env, jclass obj,
+  jlong sem)
+{
+	JTHROW_neg1(sem_close((sem_t *)(intptr_t)sem))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1destroy(JNIEnv *env, jclass obj,
+  jlong sem)
+{
+	JTHROW_neg1(sem_destroy((sem_t *)(intptr_t)sem))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1getvalue(JNIEnv *env, jclass obj,
+  jlong sem, jobject valuep)
+{
+	int value_c, r;
+	jclass cls = (*env)->FindClass(env, "jtux/UUtil$IntHolder");
+
+	JTHROW_neg1(r = sem_getvalue((sem_t *)(intptr_t)sem, &value_c))
+	if (valuep != NULL && r != -1) {
+		if (!field_ctoj_int(env, cls, "value", valuep, value_c))
+			return;
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1init(JNIEnv *env, jclass obj,
+  jlong sem, jint pshared, jint value)
+{
+	JTHROW_neg1(sem_init((sem_t *)(intptr_t)sem, pshared, value))
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_sem_1open__Ljava_lang_String_2I(JNIEnv *env, jclass obj,
+  jstring name, jint flags)
+{
+	JSTR_GET_DECL(name_c, name)
+	sem_t *sem;
+
+	JSTR_NULLTEST_V(name_c, 0)
+	if ((sem = sem_open(name_c, flags)) == SEM_FAILED)
+		JTHROW_null(NULL)
+	JSTR_REL(name_c, name)
+	return (intptr_t)sem;
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UPosixIPC_sem_1open__Ljava_lang_String_2III(JNIEnv *env, jclass obj,
+  jstring name, jint flags, jint perms, jint value)
+{
+	JSTR_GET_DECL(name_c, name)
+	sem_t *sem;
+
+	JSTR_NULLTEST_V(name_c, 0)
+	if ((sem = sem_open(name_c, flags, perms, value)) == SEM_FAILED)
+		JTHROW_null(NULL)
+	JSTR_REL(name_c, name)
+	return (intptr_t)sem;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1post(JNIEnv *env, jclass obj,
+  jlong sem)
+{
+	JTHROW_neg1(sem_post((sem_t *)(intptr_t)sem))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1timedwait(JNIEnv *env, jclass obj,
+  jlong sem, jobject tmout)
+{
+#if _XOPEN_VERSION >= 600 || true
+// Following compiled but not tested
+	jclass cls_timespec = (*env)->FindClass(env, "jtux/UProcess$s_timespec");
+	struct timespec tmout_c;
+	long sec;
+
+	if (!field_jtoc_long(env, cls_timespec, "tv_sec", tmout, &sec))
+		return;
+	tmout_c.tv_sec = (time_t)sec;
+	if (!field_jtoc_long(env, cls_timespec, "tv_nsec", tmout, &tmout_c.tv_nsec))
+		return;
+	JTHROW_neg1(sem_timedwait((sem_t *)(intptr_t)sem, &tmout_c))
+#else
+	(void)setup_throw_errno(env, ENOSYS);
+#endif
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1trywait(JNIEnv *env, jclass obj,
+  jlong sem)
+{
+	JTHROW_neg1(sem_trywait((sem_t *)(intptr_t)sem))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1unlink(JNIEnv *env, jclass obj,
+  jstring name)
+{
+	JSTR_GET_DECL(name_c, name)
+
+	JSTR_NULLTEST(name_c)
+	JTHROW_neg1(sem_unlink(name_c))
+	JSTR_REL(name_c, name)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_sem_1wait(JNIEnv *env, jclass obj,
+  jlong sem)
+{
+	JTHROW_neg1(sem_wait((sem_t *)(intptr_t)sem))
+}
+
+
+JNIEXPORT jint JNICALL Java_jtux_UPosixIPC_shm_1open(JNIEnv *env, jclass obj,
+  jstring name, jint flags, jint perms)
+{
+	JSTR_GET_DECL(name_c, name)
+	int fd;
+
+	JSTR_NULLTEST_V(name_c, -1)
+	JTHROW_neg1(fd = shm_open(name_c, flags, perms))
+	JSTR_REL(name_c, name)
+	return fd;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UPosixIPC_shm_1unlink(JNIEnv *env, jclass obj,
+  jstring name)
+{
+	JSTR_GET_DECL(name_c, name)
+
+	JSTR_NULLTEST(name_c)
+	JTHROW_neg1(shm_unlink(name_c))
+	JSTR_REL(name_c, name)
+}
diff --git a/jtux_process.c b/jtux_process.c
new file mode 100755
index 0000000..2756203
--- /dev/null
+++ b/jtux_process.c
@@ -0,0 +1,902 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+#ifdef SOLARIS
+// needed for setegid and seteuid
+#define __EXTENSIONS__
+#endif
+
+/*
+	Need to prevent GNU from using the wrong prototype for functions declared in
+	sys/resource.h (see comment there). As sys/wait.h (included by defs.h) brings
+	in this include (on GNU systems, anyway), there is a special symbol (AUP2_SKIP_WAIT)
+	used in defs.h to suppress that include. Also, we should not have to undef __USE_GNU
+	(I think), we seem to have to do that as well.
+
+	(It would have been much better if the GNU folks had not tried to improve things!)
+*/
+
+#define AUP2_SKIP_WAIT
+#include "defs.h"
+
+#ifdef _GNU_SOURCE
+#define _GNU_SOURCE_WAS_DEFINED
+#undef _GNU_SOURCE
+#undef __USE_GNU
+#endif
+#include <sys/resource.h>
+#ifdef _GNU_SOURCE_WAS_DEFINED
+#define _GNU_SOURCE
+#undef _GNU_SOURCE_WAS_DEFINED
+#endif
+
+#include <sys/wait.h> // now it is OK to bring it in
+#include <sys/times.h>
+#include <pthread.h>
+#include "JtuxProcess.h" // generated by javah
+#include "JtuxProcess$sigset_t.h" // generated by javah
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+static long get_max_pathname(const char *path)
+{
+	long max_path;
+	errno = 0;
+	max_path = pathconf(path, _PC_PATH_MAX);
+	if (max_path == -1) {
+		if (errno == 0)
+			max_path = 4096; /* guess */
+		else
+			max_path = 4096; /* bury the error -- return guess here, too */
+	}
+	return max_path + 1;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UProcess_00024sigset_1t_GetSize_1sigset_1t(JNIEnv *env, jclass obj)
+{
+
+	return sizeof(sigset_t);
+}
+
+#if 0 // all obsolete -- get rid of this stuff
+static jbyteArray get_bytearray_sigset(JNIEnv *env, jclass obj)
+{
+	jclass sigset_t_class = (*env)->FindClass(env, "jtux/UProcess$sigset_t");
+	jfieldID fid;
+
+	if (sigset_t_class == NULL)
+		return NULL;
+	if ((fid = (*env)->GetFieldID(env, sigset_t_class, "set", "[B")) == NULL)
+		return NULL;
+	return (*env)->GetObjectField(env, obj, fid);
+}
+
+static bool get_sigset(JNIEnv *env, jclass obj, sigset_t *set)
+{
+	jbyteArray bytes = get_bytearray_sigset(env, obj);
+
+	if (bytes == NULL)
+		return false;
+	(*env)->GetByteArrayRegion(env, bytes, 0, sizeof(sigset_t), (jbyte *)set);
+	return true;
+}
+
+static bool set_sigset(JNIEnv *env, jclass obj, sigset_t *set)
+{
+	jbyteArray bytes = get_bytearray_sigset(env, obj);
+
+	if (bytes == NULL)
+		return false;
+	(*env)->SetByteArrayRegion(env, bytes, 0, sizeof(sigset_t), (jbyte *)set);
+	return true;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigaddset(JNIEnv *env, jclass obj,
+  jint signum)
+{
+	sigset_t set;
+
+	if (!get_sigset(env, obj, &set))
+		return;
+	JTHROW_neg1(sigaddset(&set, signum))
+	(void)set_sigset(env, obj, &set);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigdelset(JNIEnv *env, jclass obj,
+  jint signum)
+{
+	sigset_t set;
+
+	if (!get_sigset(env, obj, &set))
+		return;
+	JTHROW_neg1(sigdelset(&set, signum))
+	(void)set_sigset(env, obj, &set);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigemptyset(JNIEnv *env, jclass obj)
+{
+	sigset_t set;
+
+	if (!get_sigset(env, obj, &set))
+		return;
+	JTHROW_neg1(sigemptyset(&set))
+	(void)set_sigset(env, obj, &set);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigfillset(JNIEnv *env, jclass obj)
+{
+	sigset_t set;
+
+	if (!get_sigset(env, obj, &set))
+		return;
+	JTHROW_neg1(sigfillset(&set))
+	(void)set_sigset(env, obj, &set);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UProcess_00024sigset_1t_sigismember(JNIEnv *env, jclass obj,
+  jint signum)
+{
+	sigset_t set;
+	int r;
+
+	if (!get_sigset(env, obj, &set))
+		return;
+	JTHROW_neg1(r = sigismember(&set, signum))
+	return r != 0;
+}
+#endif// all obsolete -- get rid of this stuff
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_abort(JNIEnv *env, jclass obj)
+{
+	abort();
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_chdir(JNIEnv *env, jclass obj, jstring s)
+{
+	JSTR_GET_DECL(s_c, s)
+
+	JSTR_NULLTEST(s_c)
+	JTHROW_neg1(chdir(s_c))
+	JSTR_REL(s_c, s)
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_chroot(JNIEnv *env, jclass obj, jstring s)
+{
+	JSTR_GET_DECL(s_c, s)
+
+	JSTR_NULLTEST(s_c)
+	JTHROW_neg1(chroot(s_c))
+	JSTR_REL(s_c, s)
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_clock(JNIEnv *env, jclass obj)
+{
+	clock_t c;
+
+	errno = 0; // because SUS doesn't say it's set
+	JTHROW_neg1(c = clock())
+	return c;
+}
+
+/**
+	Calls ::clock.
+*/
+/* static  clock_t UProcess::clock(void)
+{
+	clock_t c;
+
+	errno = 0;
+	if ((c = ::clock()) == -1) {
+		if (errno == 0)
+			throw Error(EINVAL);
+		else
+			throw Error(errno);
+	}
+	return c;
+}*/
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_execvp(JNIEnv *env, jclass obj, jstring s, jobjectArray a)
+{
+	JSTR_GET_DECL(s_c, s)
+	const char **argv = NULL;
+	int i, argc;
+	jsize array_size = (*env)->GetArrayLength(env, a);
+	jobject arg;
+
+	JSTR_NULLTEST(s_c)
+	for (argc = 0; argc < array_size && (*env)->GetObjectArrayElement(env, a, argc) != NULL; argc++)
+		;
+	argv = malloc((argc + 1) * sizeof(char *));
+	if (argv == NULL) {
+		(void)setup_throw_errno(env, errno);
+		return;
+	}
+	for (i = 0; i < argc; i++) {
+		arg = (*env)->GetObjectArrayElement(env, a, i);
+		if ((*env)->ExceptionCheck(env)) { // why isn't this a check on arg == NULL?
+			free(argv);
+			JSTR_REL(s_c, s)
+			return;
+		}
+		argv[i] = (*env)->GetStringUTFChars(env, arg, NULL);
+	}
+	argv[i] = NULL;
+	JTHROW_neg1(execvp(s_c, (char **)argv))
+	/*
+		Release arguments only when execvp fails
+		************ Code is suspect -- jython complains!
+	*/
+	for (i = 0; i < argc; i++)
+		JSTR_REL(argv[i], (*env)->GetObjectArrayElement(env, a, i))
+	JSTR_REL(s_c, s)
+	free(argv);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_exit(JNIEnv *env, jclass obj, jint n)
+{
+	exit(n);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess__1exit(JNIEnv *env, jclass obj, jint n)
+{
+	_exit(n);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_fchdir(JNIEnv *env, jclass obj, jint n)
+{
+	JTHROW_neg1(fchdir(n))
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_fork(JNIEnv *env, jclass obj)
+{
+	jlong n;
+	JavaVM *vm;
+
+	(void)(*env)->GetJavaVM(env, &vm);
+	JTHROW_neg1(n = fork())
+	if (n == 0) {
+		JNIEnv *envnew; // not clear what to do with this
+		(void)(*vm)->AttachCurrentThread(vm, (void **)&envnew, NULL);
+	}
+	return n;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_getcwd(JNIEnv *env, jclass obj, jobject path)
+{
+	char *pathbuf, *r;
+	long maxpath;
+
+	JTHROW_null(pathbuf = malloc(maxpath = get_max_pathname(".")))
+	if (pathbuf == NULL)
+		return;
+	JTHROW_null(r = getcwd(pathbuf, maxpath))
+	if (r != NULL)
+		(void)string_buffer_set(env, path, pathbuf);
+	free(pathbuf);
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getegid(JNIEnv *env, jclass obj)
+{
+	return getegid();
+}
+
+JNIEXPORT jstring JNICALL Java_jtux_UProcess_getenv(JNIEnv *env, jclass obj, jstring s)
+{
+	JSTR_GET_DECL(s_c, s)
+	char *r = NULL;
+
+	JSTR_NULLTEST_V(s_c, NULL)
+	r = getenv(s_c);
+	JSTR_REL(s_c, s)
+	JSTR_RETURN(r)
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_geteuid(JNIEnv *env, jclass obj)
+{
+	return geteuid();
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getgid(JNIEnv *env, jclass obj)
+{
+	return getgid();
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getpgid(JNIEnv *env, jclass obj, jlong pid)
+{
+	long r;
+
+	JTHROW_neg1(r = getpgid(pid))
+	return r;
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getpid(JNIEnv *env, jclass obj)
+{
+	return getpid();
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getppid(JNIEnv *env, jclass obj)
+{
+	return getppid();
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_getrlimit(JNIEnv *env, jclass obj,
+  jint resource, jobject rl)
+{
+	struct rlimit rlim;
+	jclass rlclass = (*env)->FindClass(env, "jtux/UProcess$s_rlimit");
+	jfieldID fid;
+
+	if (rlclass == NULL)
+		return;
+	JTHROW_neg1(getrlimit(resource, &rlim))
+	if ((*env)->ExceptionCheck(env))
+		return;
+	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_cur", "J")) == NULL)
+		return;
+	(*env)->SetLongField(env, rl, fid, rlim.rlim_cur);
+	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_max", "J")) == NULL)
+		return;
+	(*env)->SetLongField(env, rl, fid, rlim.rlim_max);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_getrusage(JNIEnv *env, jclass obj,
+  jint who, jobject r_usage)
+{
+	struct rusage ru;
+	jclass ruclass = (*env)->FindClass(env, "jtux/UProcess$s_rusage");
+	jclass tmsclass;
+	jfieldID fid, fid_tv_sec, fid_tv_usec;
+	jobject objtms;
+
+	if (ruclass == NULL)
+		return;
+	JTHROW_neg1(getrusage(who, &ru))
+	if ((*env)->ExceptionCheck(env))
+		return;
+	if ((tmsclass = (*env)->FindClass(env, "jtux/UProcess$s_timeval")) == NULL)
+		return;
+	if ((fid_tv_sec = (*env)->GetFieldID(env, tmsclass, "tv_sec", "J")) == NULL)
+		return;
+	if ((fid_tv_usec = (*env)->GetFieldID(env, tmsclass, "tv_usec", "J")) == NULL)
+		return;
+	// set ru_utime
+	if ((fid = (*env)->GetFieldID(env, ruclass, "ru_utime", "Ljtux/UProcess$s_timeval;"))
+	  == NULL)
+		return;
+	if ((objtms = (*env)->GetObjectField(env, r_usage, fid)) == NULL)
+		return;
+	(*env)->SetLongField(env, objtms, fid_tv_sec, ru.ru_utime.tv_sec);
+	(*env)->SetLongField(env, objtms, fid_tv_usec, ru.ru_utime.tv_usec);
+	// set ru_stime
+	if ((fid = (*env)->GetFieldID(env, ruclass, "ru_stime", "Ljtux/UProcess$s_timeval;"))
+	  == NULL)
+		return;
+	if ((objtms = (*env)->GetObjectField(env, r_usage, fid)) == NULL)
+		return;
+	(*env)->SetLongField(env, objtms, fid_tv_sec, ru.ru_stime.tv_sec);
+	(*env)->SetLongField(env, objtms, fid_tv_usec, ru.ru_stime.tv_usec);
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getsid(JNIEnv *env, jclass obj, jlong pid)
+{
+	long r;
+
+	JTHROW_neg1(r = getsid(pid))
+	return r;
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_getuid(JNIEnv *env, jclass obj)
+{
+	return getuid();
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_kill(JNIEnv *env, jclass obj, jlong pid, jlong signum)
+{
+	JTHROW_neg1(kill(pid, (int)signum))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_nice(JNIEnv *env, jclass obj, jint incr)
+{
+	JTHROW_neg1(nice(incr))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_pause(JNIEnv *env, jclass obj)
+{
+	JTHROW_neg1(pause());
+}
+
+/*
+	See comment for sigprocmask.
+*/
+JNIEXPORT void JNICALL Java_jtux_UProcess_pthread_1sigmask(JNIEnv *env, jclass obj, jint how,
+  jobject set, jobject oset)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+#if 0 // not redone for new sigset_t approach
+	sigset_t set_c, oset_c;
+
+	if (get_sigset(env, set, &set_c)) {
+		JTHROW_rv(pthread_sigmask(how, &set_c, &oset_c))
+		if (!(*env)->ExceptionCheck(env) && oset != NULL)
+			(void)set_sigset(env, oset, &oset_c);
+	}
+#endif
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_putenv(JNIEnv *env, jclass obj,
+  jstring string)
+{
+	JSTR_GET_DECL(string_c, string)
+
+	JSTR_NULLTEST(string_c)
+	JTHROW_nzero(putenv((char *)string_c))
+	// Do not release string_c -- it is now in the environment
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_setenv(JNIEnv *env, jclass obj,
+  jstring var, jstring val, jboolean overwrite)
+{
+#if _XOPEN_VERSION >= 600 || defined(LINUX) || defined(FREEBSD)
+	JSTR_GET_DECL(var_c, var)
+	JSTR_GET_DECL(val_c, val)
+
+	JSTR_NULLTEST(var_c)
+	JSTR_NULLTEST(val_c)
+	JTHROW_neg1(setenv(var_c, val_c, overwrite))
+	JSTR_REL(var_c, var)
+	JSTR_REL(var_c, val)
+#else
+	(void)setup_throw_errno(env, ENOSYS);
+#endif
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_setegid(JNIEnv *env, jclass obj, jlong gid)
+{
+	JTHROW_neg1(setegid(gid))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_seteuid(JNIEnv *env, jclass obj, jlong uid)
+{
+	JTHROW_neg1(seteuid(uid))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_setgid(JNIEnv *env, jclass obj, jlong gid)
+{
+	JTHROW_neg1(setgid(gid))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_setpgid(JNIEnv *env, jclass obj, jlong pid, jlong pgid)
+{
+	JTHROW_neg1(setpgid(pid, pgid))
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_setrlimit(JNIEnv *env, jclass obj,
+  jint resource, jobject rl)
+{
+	struct rlimit rlim;
+	jclass rlclass = (*env)->FindClass(env, "jtux/UProcess$s_rlimit");
+	jfieldID fid;
+
+	if (rlclass == NULL)
+		return;
+	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_cur", "J")) == NULL)
+		return;
+	rlim.rlim_cur = (*env)->GetLongField(env, rl, fid);
+	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_max", "J")) == NULL)
+		return;
+	rlim.rlim_max = (*env)->GetLongField(env, rl, fid);
+	JTHROW_neg1(setrlimit(resource, &rlim))
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_setsid(JNIEnv *env, jclass obj)
+{
+	long r;
+
+	JTHROW_neg1(r = setsid())
+	return r;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_setuid(JNIEnv *env, jclass obj, jlong uid)
+{
+	JTHROW_neg1(setuid(uid))
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UProcess_sig_1get_1SIGRTMIN(JNIEnv *env, jclass obj)
+{
+	return SIGRTMIN;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UProcess_sig_1get_1SIGRTMAX(JNIEnv *env, jclass obj)
+{
+	return SIGRTMAX;
+}
+
+static JavaVM *vm;
+
+static void fcn_handler(int signum)
+{
+	JNIEnv *env;
+	jmethodID mid_sig;
+	jclass Processclass;
+
+	(void)write(STDOUT_FILENO, "Got signal\n", 11);
+	if ((*vm)->AttachCurrentThread(vm, (void **)&env, NULL) == 0) {
+		Processclass = (*env)->FindClass(env, "jtux/UProcess");
+		if (Processclass == NULL) {
+			return;
+		}
+		mid_sig = (*env)->GetStaticMethodID(env, Processclass, "CatchSignal", "(I)V");
+		if (mid_sig == NULL) {
+			return;
+		}
+		(*env)->CallStaticVoidMethod(env, Processclass, mid_sig, (jint)signum);
+	}
+}
+
+static void fcn_sigaction(int signum, siginfo_t *info, void *context)
+{
+	JNIEnv *env;
+	jmethodID mid_sig;
+	jclass cls_Process;
+
+	(void)write(STDOUT_FILENO, "fcn_sigaction got signal\n", 25);
+	{
+		// Just a test -- not part of the algorithm.
+		JavaVM *jvmbuf[100];
+		jsize nvms;
+		int i;
+
+		if (JNI_GetCreatedJavaVMs(jvmbuf, sizeof(jvmbuf), &nvms) == -1)
+			printf("JNI_GetCreatedJavaVMs failed");
+		for (i = 0; i < nvms; i++)
+			printf("JVM #%d: 0x%lx\n", i, (long)jvmbuf[i]);
+		printf("JVM passed as vm: 0x%lx\n", (long)vm);
+	}
+	if ((*vm)->AttachCurrentThread(vm, (void **)&env, NULL) == 0) {
+		jclass cls_siginfo_t = (*env)->FindClass(env, "jtux/UProcess$siginfo_t");
+		jclass cls_u_sigval_int = (*env)->FindClass(env, "jtux/UProcess$u_sigval_int");
+		jmethodID mid;
+		jobject si = NULL, sval;
+
+		if (cls_u_sigval_int == NULL) {
+			fprintf(stderr, "*** Jtux: fcn_sigaction -- can't get class jtux/UProcess$cls_u_sigval_int\n");
+			return;
+		}
+		if (cls_siginfo_t == NULL) {
+			fprintf(stderr, "*** Jtux: fcn_sigaction -- can't get class jtux/UProcess$siginfo_t\n");
+			return;
+		}
+		/*
+			When a NewObject is created in this signal handler, it's passed OK to the
+			Java signal handler, but later in another part of the program a child process
+			waiting on a semaphore (totally unrelated) gets hung up (not even in a
+			sem_wait). This indicates that something is seriously amiss. Until it's
+			solved, this part is disabled so a 3-arg sa_sigaction handler can't get
+			the info argument as anything other than NULL.
+		*/
+		if (info != NULL && false /* temporary disabling*/) {
+			if ((mid = (*env)->GetMethodID(env, cls_siginfo_t, "<init>", "()V")) == NULL)
+				return;
+			if ((si = (*env)->NewObject(env, cls_siginfo_t, mid)) == NULL)
+				return;
+			if ((mid = (*env)->GetMethodID(env, cls_u_sigval_int, "<init>", "()V")) == NULL)
+				return;
+			if ((sval = (*env)->NewObject(env, cls_u_sigval_int, mid)) == NULL)
+				return;
+			if (!field_ctoj_int(env, cls_siginfo_t, "si_signo", si, info->si_signo))
+				return;
+			if (!field_ctoj_int(env, cls_siginfo_t, "si_errno", si, info->si_errno))
+				return;
+			if (!field_ctoj_int(env, cls_siginfo_t, "si_code", si, info->si_code))
+				return;
+			if (!field_ctoj_long(env, cls_siginfo_t, "si_pid", si, info->si_pid))
+				return;
+			if (!field_ctoj_long(env, cls_siginfo_t, "si_uid", si, info->si_uid))
+				return;
+			if (!field_ctoj_long(env, cls_siginfo_t, "si_addr", si, (intptr_t)info->si_addr))
+				return;
+			if (!field_ctoj_int(env, cls_siginfo_t, "si_status", si, info->si_status))
+				return;
+			if (!field_ctoj_long(env, cls_siginfo_t, "si_band", si, info->si_band))
+				return;
+
+			//	Always assume int, since there's no way to tell if the ptr member was used
+			//	anyway.
+			if (!field_ctoj_int(env, cls_u_sigval_int, "sival_int", sval, info->si_value.sival_int))
+				return;
+			if (!field_ctoj_object(env, cls_siginfo_t, "si_value", "Ljtux/UProcess$u_sigval;", si, sval))
+				return;
+		}
+		if ((cls_Process = (*env)->FindClass(env, "jtux/UProcess")) == NULL)
+			return;
+		if ((mid_sig = (*env)->GetStaticMethodID(env, cls_Process, "CatchSignal", "(ILjtux/UProcess$siginfo_t;J)V"))
+		  == NULL)
+			return;
+		(*env)->CallStaticVoidMethod(env, cls_Process, mid_sig, (jint)signum, si, (jlong)(intptr_t)context);
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigaction_1x(JNIEnv *env, jclass obj, jint signum,
+  jobject act, jobject oact)
+{
+	jclass sclass = (*env)->FindClass(env, "jtux/UProcess$s_sigaction");
+	struct sigaction sigact;
+	int actiontype;
+
+#ifdef WANT_LIST_OF_SIGNALS
+{
+	int n;
+
+	for (n = 1; n <= 30; n++) {
+		if (sigaction(n, NULL, &sigact) == -1)
+			continue;
+		if (sigact.sa_handler == SIG_IGN || sigact.sa_handler == SIG_DFL)
+			printf("%s is ignored or defaulted\n", get_macrostr("signal", n, NULL));
+		else
+			printf("%s is caught\n", get_macrostr("signal", n, NULL));
+	}
+}
+#endif
+	memset(&sigact, 0, sizeof(sigact));
+	if (!field_jtoc_int(env, sclass, "sa_actiontype", act, &actiontype))
+		return;
+	if (!field_jtoc_int(env, sclass, "sa_flags", act, &sigact.sa_flags))
+		return;
+	if (actiontype == (int)SIG_IGN || actiontype == (int)SIG_DFL)
+		sigact.sa_handler = (void (*)(int))actiontype;
+	else if ((sigact.sa_flags & SA_SIGINFO) == SA_SIGINFO) {
+		sigact.sa_sigaction = fcn_sigaction;
+}
+	else {
+		sigact.sa_handler = fcn_handler;
+}
+	//pthread_sigmask(SIG_SETMASK, &sigact.sa_mask, NULL);
+	JTHROW_neg1(sigaction(signum, &sigact, NULL))
+
+#if 0
+		int sa_actiontype;
+		Method sa_handler;
+		sigset_t sa_mask;
+		int sa_flags;
+#endif
+	if ((*env)->GetJavaVM(env, &vm) < 0)
+		return;
+
+
+#if 0
+	act.sa_handler = SIG_DFL;
+	JTHROW_neg1(sigaction(SIGQUIT, &act, NULL))
+#endif
+	//printf("signals setup\n");
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigaddset(JNIEnv *env, jclass obj,
+  jobject set, jint signum)
+{
+	jbyteArray ba;
+	jbyte *b = get_sigset(env, set, &ba);
+
+	if (b != NULL) {
+		JTHROW_neg1(sigaddset((sigset_t *)b, signum))
+		release_sigset(env, ba, b);
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigaltstack(JNIEnv *env, jclass obj,
+  jobject stack, jobject ostack)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+}
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigdelset(JNIEnv *env, jclass obj,
+  jobject set, jint signum)
+{
+	jbyteArray ba;
+	jbyte *b = get_sigset(env, set, &ba);
+
+	if (b != NULL) {
+		JTHROW_neg1(sigdelset((sigset_t *)b, signum))
+		release_sigset(env, ba, b);
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigemptyset(JNIEnv *env, jclass obj,
+  jobject set)
+{
+	jbyteArray ba;
+	jbyte *b = get_sigset(env, set, &ba);
+
+	if (b != NULL) {
+		JTHROW_neg1(sigemptyset((sigset_t *)b))
+		release_sigset(env, ba, b);
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigfillset(JNIEnv *env, jclass obj,
+  jobject set)
+{
+	jbyteArray ba;
+	jbyte *b = get_sigset(env, set, &ba);
+
+	if (b != NULL) {
+		JTHROW_neg1(sigfillset((sigset_t *)b))
+		release_sigset(env, ba, b);
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_siginterrupt(JNIEnv *env, jclass obj,
+  jint signum, jint on)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+}
+
+JNIEXPORT jboolean JNICALL Java_jtux_UProcess_sigismember(JNIEnv *env, jclass obj,
+  jobject set, jint signum)
+{
+	jbyteArray ba;
+	jbyte *b = get_sigset(env, set, &ba);
+	int r = 0;
+
+	if (b != NULL) {
+		JTHROW_neg1(r = sigismember((sigset_t *)b, signum))
+		release_sigset(env, ba, b);
+	}
+	return r != 0;
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigpending(JNIEnv *env, jclass obj, jobject set)
+{
+	jbyteArray ba;
+	jbyte *b = get_sigset(env, set, &ba);
+
+	if (b != NULL) {
+		JTHROW_neg1(sigpending((sigset_t *)b))
+		release_sigset(env, ba, b);
+	}
+}
+
+/*
+	Ineffective because of multithreaded JVM environment. Mask affects only thread, but
+	other threads (over which we have no control) with the signal unblocked will still
+	get the signal.
+*/
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigprocmask(JNIEnv *env, jclass obj, jint how,
+  jobject set, jobject oset)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+#if 0 // not redone for new sigset_t approach
+	sigset_t set_c, oset_c;
+
+#if 0
+{
+	sigset_t s;
+
+	if (sigemptyset(&s) == -1 ||
+	  sigaddset(&s, SIGPROF) == -1 ||
+	  sigprocmask(SIG_SETMASK, &s, NULL) == -1 ||
+	  kill(getpid(), SIGPROF) == -1)
+		printf("bad sys call in Java_jtux_UProcess_sigprocmask\n");
+	else
+		printf("^^^^^^^^^^^^^^^^ I am still alive.\n");
+}
+#endif
+	if (get_sigset(env, set, &set_c)) {
+		JTHROW_neg1(sigprocmask(how, &set_c, &oset_c))
+		if (!(*env)->ExceptionCheck(env) && oset != NULL)
+			(void)set_sigset(env, oset, &oset_c);
+	}
+#endif
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigqueue(JNIEnv *env, jclass obj,
+  jlong pid, jint signum, jobject value)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigsuspend(JNIEnv *env, jclass obj,
+  jobject set)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigtimedwait(JNIEnv *env, jclass obj,
+  jobject set, jobject info, jobject ts)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigwait(JNIEnv *env, jclass obj,
+  jobject set, jobject signum)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_sigwaitinfo(JNIEnv *env, jclass obj,
+  jobject set, jobject info)
+{
+	(void)setup_throw_errno(env, ENOSYS);
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UProcess_system(JNIEnv *env, jclass obj, jstring s)
+{
+	JSTR_GET_DECL(s_c, s)
+	jint n;
+
+	JSTR_NULLTEST_V(s_c, -1)
+	JTHROW_neg1(n = system(s_c))
+	JSTR_REL(s_c, s)
+	return n;
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_times(JNIEnv *env, jclass obj, jobject buffer)
+{
+	clock_t t;
+	struct tms tbuf;
+	jclass tmsclass = (*env)->FindClass(env, "jtux/UProcess$s_tms");
+
+	JTHROW_neg1(t = times(&tbuf))
+	if (!field_ctoj_long(env, tmsclass, "tms_utime", buffer, tbuf.tms_utime))
+		return -1;
+	if (!field_ctoj_long(env, tmsclass, "tms_stime", buffer, tbuf.tms_stime))
+		return -1;
+	if (!field_ctoj_long(env, tmsclass, "tms_cutime", buffer, tbuf.tms_cutime))
+		return -1;
+	if (!field_ctoj_long(env, tmsclass, "tms_cstime", buffer, tbuf.tms_cstime))
+		return -1;
+	return t;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_UProcess_umask(JNIEnv *env, jclass obj,
+  jint cmask)
+{
+	return umask(cmask);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UProcess_unsetenv(JNIEnv *env, jclass obj,
+  jstring var)
+{
+#if _XOPEN_VERSION >= 600 || defined(LINUX) || defined(FREEBSD)
+	JSTR_GET_DECL(var_c, var)
+
+	JSTR_NULLTEST(var_c)
+	JTHROW_neg1(unsetenv(var_c))
+	JSTR_REL(var_c, var)
+#else
+	(void)setup_throw_errno(env, ENOSYS);
+#endif
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_UProcess_waitpid(JNIEnv *env, jclass obj, jlong pid,
+  jobject status, jint options)
+{
+	pid_t rtn_pid;
+	int status_c;
+
+	JTHROW_neg1(rtn_pid = waitpid(pid, &status_c, options))
+	if (rtn_pid == -1)
+		return -1;
+	if (status != NULL) {
+		jclass ExitStatusclass;
+		jmethodID mid;
+
+		ExitStatusclass = (*env)->GetObjectClass(env, status);
+		if ((mid = (*env)->GetMethodID(env, ExitStatusclass, "set", "(I)V")) == NULL)
+			return -1;
+		(*env)->CallIntMethod(env, status, mid, status_c);
+	}
+	return rtn_pid;
+}
\ No newline at end of file
diff --git a/jtux_sysvipc.c b/jtux_sysvipc.c
new file mode 100755
index 0000000..33f2267
--- /dev/null
+++ b/jtux_sysvipc.c
@@ -0,0 +1,362 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+
+#include "defs.h"
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include "JtuxSysVIPC.h" // generated by javah
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+static bool field_jtoc_perm(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  struct ipc_perm *perm)
+{
+	jfieldID fid;
+	jclass clsperm = (*env)->FindClass(env, "jtux/USysVIPC$s_ipc_perm");
+	jobject objperm;
+	int mode;
+
+	if (cls == NULL || clsperm == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "Ljtux/USysVIPC$s_ipc_perm;")) == NULL)
+		return false;
+	if ((objperm = (*env)->GetObjectField(env, obj, fid)) == NULL) {
+		JNU_ThrowByName(env, "NullPointerException", "s_ipc_perm field not initialized");
+		return false;
+	}
+	if (!field_jtoc_long(env, clsperm, "uid", objperm, &perm->uid))
+		return false;
+	if (!field_jtoc_long(env, clsperm, "gid", objperm, &perm->gid))
+		return false;
+	if (!field_jtoc_long(env, clsperm, "cuid", objperm, &perm->cuid))
+		return false;
+	if (!field_jtoc_long(env, clsperm, "cgid", objperm, &perm->cgid))
+		return false;
+	if (!field_jtoc_int(env, clsperm, "mode", objperm, &mode))
+		return false;
+	perm->mode = mode;
+	return true;
+}
+
+static bool field_ctoj_perm(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  struct ipc_perm *perm)
+{
+	jfieldID fid;
+	jclass clsperm = (*env)->FindClass(env, "jtux/USysVIPC$s_ipc_perm");
+	jobject objperm;
+
+	if (cls == NULL || clsperm == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "Ljtux/USysVIPC$s_ipc_perm;")) == NULL)
+		return false;
+	if ((objperm = (*env)->GetObjectField(env, obj, fid)) == NULL) {
+		JNU_ThrowByName(env, "NullPointerException", "s_ipc_perm field not initialized");
+		return false;
+	}
+	if (!field_ctoj_long(env, clsperm, "uid", objperm, perm->uid))
+		return false;
+	if (!field_ctoj_long(env, clsperm, "gid", objperm, perm->gid))
+		return false;
+	if (!field_ctoj_long(env, clsperm, "cuid", objperm, perm->cuid))
+		return false;
+	if (!field_ctoj_long(env, clsperm, "cgid", objperm, perm->cgid))
+		return false;
+	if (!field_ctoj_int(env, clsperm, "mode", objperm, perm->mode))
+		return false;
+	return true;
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_ftok(JNIEnv *env, jclass obj,
+  jstring path, jint id)
+{
+	JSTR_GET_DECL(path_c, path)
+	key_t k;
+
+	JSTR_NULLTEST_V(path_c, -1)
+	JTHROW_neg1(k = ftok(path_c, id))
+	JSTR_REL(path_c, path)
+	return k;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msg_1set_1type(JNIEnv *env, jclass obj,
+  jlong msgtype, jbyteArray msgp)
+{
+	void *msgp_c;
+
+	if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
+		return 0;
+	*(long *)msgp_c = (long)msgtype;
+	(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
+	return sizeof(long);
+}
+
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgctl(JNIEnv *env, jclass obj,
+  jint msqid, jint cmd, jobject data)
+{
+	struct msqid_ds data_c;
+	jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_msqid_ds");
+	int n, r;
+
+	memset(&data_c, 0, sizeof(data_c));
+	if (cmd == IPC_SET) {
+		if (!field_jtoc_perm(env, cls, "msg_perm", data, &data_c.msg_perm))
+			return;
+		if (!field_jtoc_int(env, cls, "msg_qbytes", data, &n))
+			return;
+		data_c.msg_qbytes = n;
+	}
+	JTHROW_neg1(r = msgctl(msqid, cmd, &data_c))
+	if (r == -1)
+		return;
+	if (cmd == IPC_STAT) {
+		if (!field_ctoj_perm(env, cls, "msg_perm", data, &data_c.msg_perm))
+			return;
+		if (!field_ctoj_int(env, cls, "msg_qnum", data, data_c.msg_qnum))
+			return;
+		if (!field_ctoj_int(env, cls, "msg_qbytes", data, data_c.msg_qbytes))
+			return;
+		if (!field_ctoj_long(env, cls, "msg_lspid", data, data_c.msg_lspid))
+			return;
+		if (!field_ctoj_long(env, cls, "msg_lrpid", data, data_c.msg_lrpid))
+			return;
+		if (!field_ctoj_long(env, cls, "msg_stime", data, data_c.msg_stime))
+			return;
+		if (!field_ctoj_long(env, cls, "msg_rtime", data, data_c.msg_rtime))
+			return;
+		if (!field_ctoj_long(env, cls, "msg_ctime", data, data_c.msg_ctime))
+			return;
+	}
+}
+
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgget(JNIEnv *env, jclass obj,
+  jlong key, jint flags)
+{
+	int msqid;
+
+	JTHROW_neg1(msqid = msgget(key, flags))
+	return msqid;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgrcv(JNIEnv *env, jclass obj,
+  jint msqid, jbyteArray msgp, jint mtextsize, jlong msgtype, jint flags)
+{
+	void *msgp_c;
+	ssize_t nrcv;
+
+	if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
+		return -1;
+	JTHROW_neg1(nrcv = msgrcv(msqid, msgp_c, mtextsize, msgtype, flags))
+	(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
+	return nrcv;
+}
+
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgsnd(JNIEnv *env, jclass obj,
+  jint msqid, jbyteArray msgp, jint msgsize, jint flags)
+{
+	void *msgp_c;
+
+	if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
+		return;
+	JTHROW_neg1(msgsnd(msqid, msgp_c, msgsize, flags))
+	(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
+}
+
+JNIEXPORT int JNICALL Java_jtux_USysVIPC_semctl(JNIEnv *env, jclass obj,
+  jint semid, jint semnum, jint cmd, jobject arg)
+{
+	struct semid_ds data_c;
+	jclass cls_s_semid_ds = (*env)->FindClass(env, "jtux/USysVIPC$s_semid_ds");
+	jclass cls_u_semun_int = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_int");
+	jclass cls_u_semun_struct = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_struct");
+	jclass cls_u_semun_array = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_array");
+	jfieldID fid;
+	jobject objds;
+	jshortArray array;
+	int r;
+	union semun {
+		int val;
+		struct semid_ds *buf;
+		unsigned short *array;
+	} arg_c;
+
+	memset(&data_c, 0, sizeof(data_c));
+	switch (cmd) {
+	case IPC_SET:
+		if (cls_u_semun_struct == NULL)
+			return -1;
+		if ((fid = (*env)->GetFieldID(env, cls_u_semun_struct, "buf", "Ljtux/USysVIPC$s_semid_ds;")) == NULL)
+			return -1;
+		if ((objds = (*env)->GetObjectField(env, arg, fid)) == NULL) {
+			JNU_ThrowByName(env, "NullPointerException", "buf field not initialized");
+			return -1;
+		}
+		if (!field_jtoc_perm(env, cls_s_semid_ds, "sem_perm", objds, &data_c.sem_perm))
+			return -1;
+		/* fall through */
+	case IPC_STAT:
+		arg_c.buf = &data_c;
+		break;
+	case SETVAL:
+		if (!field_jtoc_int(env, cls_u_semun_int, "val", arg, &arg_c.val))
+			return -1;
+		break;
+	case SETALL:
+	case GETALL:
+		arg_c.buf = &data_c;
+		JTHROW_neg1(r = semctl(semid, 0, IPC_STAT, arg_c))
+		if (r == -1)
+			return -1;
+		if (cls_u_semun_array == NULL)
+			return -1;
+		if ((fid = (*env)->GetFieldID(env, cls_u_semun_array, "array", "[S")) == NULL)
+			return -1;
+		if ((array = (*env)->GetObjectField(env, arg, fid)) == NULL) {
+			JNU_ThrowByName(env, "NullPointerException", "array field not initialized");
+			return -1;
+		}
+		if ((arg_c.array = (*env)->GetShortArrayElements(env, array, NULL)) == NULL)
+			return -1;
+	}
+	JTHROW_neg1(r = semctl(semid, semnum, cmd, arg_c))
+	if (r == -1)
+		return r;
+	switch (cmd) {
+	case IPC_STAT:
+		if (cls_u_semun_struct == NULL)
+			return -1;
+		if ((fid = (*env)->GetFieldID(env, cls_u_semun_struct, "buf", "Ljtux/USysVIPC$s_semid_ds;")) == NULL)
+			return -1;
+		if ((objds = (*env)->GetObjectField(env, arg, fid)) == NULL) {
+			JNU_ThrowByName(env, "NullPointerException", "s_semid_ds field not initialized");
+			return -1;
+		}
+		if (!field_ctoj_perm(env, cls_s_semid_ds, "sem_perm", objds, &data_c.sem_perm))
+			return -1;
+		if (!field_ctoj_short(env, cls_s_semid_ds, "sem_nsems", objds, data_c.sem_nsems))
+			return -1;
+		if (!field_ctoj_long(env, cls_s_semid_ds, "sem_otime", objds, data_c.sem_otime))
+			return -1;
+		if (!field_ctoj_long(env, cls_s_semid_ds, "sem_ctime", objds, data_c.sem_ctime))
+			return -1;
+		break;
+	case SETALL:
+		(*env)->ReleaseShortArrayElements(env, array, arg_c.array, JNI_ABORT);
+		break;
+	case GETALL:
+		(*env)->ReleaseShortArrayElements(env, array, arg_c.array, 0);
+	}
+	return r;
+}
+
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_semget(JNIEnv *env, jclass obj,
+  jlong key, jint msems, jint flags)
+{
+	int semid;
+
+	JTHROW_neg1(semid = semget(key, msems, flags))
+	return semid;
+}
+
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_semop(JNIEnv *env, jclass obj,
+  jint semid, jobjectArray sops, jint nsops)
+{
+	struct sembuf *sops_c;
+	int i;
+	jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_sembuf");
+
+	JTHROW_null(sops_c = malloc(nsops * sizeof(struct sembuf)))
+	if (sops_c == NULL)
+		return;
+	for (i = 0; i < nsops; i++) {
+		jobject sb_obj = (*env)->GetObjectArrayElement(env, sops, i);
+
+		if (sb_obj == NULL) {
+			free(sops_c);
+			return;
+		}
+		if (!field_jtoc_short(env, cls, "sem_num", sb_obj, &sops_c[i].sem_num))
+			return;
+		if (!field_jtoc_short(env, cls, "sem_op", sb_obj, &sops_c[i].sem_op))
+			return;
+		if (!field_jtoc_short(env, cls, "sem_flg", sb_obj, &sops_c[i].sem_flg))
+			return;
+	}
+	JTHROW_neg1(semop(semid, sops_c, nsops))
+	free(sops_c);
+}
+
+JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_shmat(JNIEnv *env, jclass obj,
+  jint shmid, jlong shmaddr, jint flags)
+{
+	intptr_t p;
+
+	JTHROW_neg1(p = (intptr_t)shmat(shmid, (const void *)(intptr_t)shmaddr, flags))
+	return p;
+}
+
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmctl(JNIEnv *env, jclass obj,
+  jint shmid, jint cmd, jobject data)
+{
+	struct shmid_ds data_c;
+	jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_shmid_ds");
+	int r;
+
+	memset(&data_c, 0, sizeof(data_c));
+	if (cmd == IPC_SET) {
+		if (!field_jtoc_perm(env, cls, "shm_perm", data, &data_c.shm_perm))
+			return;
+	}
+	JTHROW_neg1(r = shmctl(shmid, cmd, &data_c))
+	if (r == -1)
+		return;
+	if (cmd == IPC_STAT) {
+		if (!field_ctoj_perm(env, cls, "shm_perm", data, &data_c.shm_perm))
+			return;
+		if (!field_ctoj_int(env, cls, "shm_segsz", data, data_c.shm_segsz))
+			return;
+		if (!field_ctoj_long(env, cls, "shm_lpid", data, data_c.shm_lpid))
+			return;
+		if (!field_ctoj_long(env, cls, "shm_cpid", data, data_c.shm_cpid))
+			return;
+		if (!field_ctoj_int(env, cls, "shm_nattch", data, data_c.shm_nattch))
+			return;
+		if (!field_ctoj_long(env, cls, "shm_atime", data, data_c.shm_atime))
+			return;
+		if (!field_ctoj_long(env, cls, "shm_dtime", data, data_c.shm_dtime))
+			return;
+		if (!field_ctoj_long(env, cls, "shm_ctime", data, data_c.shm_ctime))
+			return;
+	}
+}
+
+JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmdt(JNIEnv *env, jclass obj,
+  jlong shmaddr)
+{
+	JTHROW_neg1(shmdt((void *)(intptr_t)shmaddr))
+}
+
+JNIEXPORT jint JNICALL Java_jtux_USysVIPC_shmget(JNIEnv *env, jclass obj,
+  jlong key, jint size, jint flags)
+{
+	int shmid;
+
+	JTHROW_neg1(shmid = shmget(key, size, flags))
+	return shmid;
+}
diff --git a/jtux_util.c b/jtux_util.c
new file mode 100755
index 0000000..646e73f
--- /dev/null
+++ b/jtux_util.c
@@ -0,0 +1,641 @@
+/*
+	Copyright 2003 by Marc J. Rochkind. All rights reserved.
+	May be copied only for purposes and under conditions described
+	on the Web page www.basepath.com/aup/copyright.htm.
+
+	The Example Files are provided "as is," without any warranty;
+	without even the implied warranty of merchantability or fitness
+	for a particular purpose. The author and his publisher are not
+	responsible for any damages, direct or incidental, resulting
+	from the use or non-use of these Example Files.
+
+	The Example Files may contain defects, and some contain deliberate
+	coding mistakes that were included for educational reasons.
+	You are responsible for determining if and how the Example Files
+	are to be used.
+
+*/
+#define __EXTENSIONS__
+#include "defs.h"
+#include <netdb.h>
+#include <sys/msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <mqueue.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include "jtux_util.h"
+#include "JNI_macros.h"
+
+/*
+	Following comes from "The Native Java Interface" (Sheng Liang; Addison-Wesley), p. 75.
+*/
+void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg)
+{
+	jclass cls = (*env)->FindClass(env, name);
+	/* if NULL, exception has already been thrown */
+	// Really want to use Throw so constructor with errno can be used.
+	if (cls != NULL)
+		(*env)->ThrowNew(env, cls, msg);
+	(*env)->DeleteLocalRef(env, cls);
+}
+
+bool setup_throw_errno(JNIEnv *env, int code)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UErrorException");
+	if (cls != NULL) {
+		jmethodID mid = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
+		if (mid != NULL) {
+			jobject obj = (*env)->NewObject(env, cls, mid, code);
+			if (obj != NULL)
+				(*env)->Throw(env, obj);
+		}
+	}
+	//char buf[200];
+
+	//(void)syserrmsgline(buf, sizeof(buf), code, EC_ERRNO);
+	//JNU_ThrowByName(env, "jtux/JtuxErrorException", buf);
+	return true;
+}
+
+bool setup_throw_errno_type(JNIEnv *env, int code, int type)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UErrorException");
+	if (cls != NULL) {
+		jmethodID mid = (*env)->GetMethodID(env, cls, "<init>", "(II)V");
+		if (mid != NULL) {
+			jobject obj = (*env)->NewObject(env, cls, mid, code, type);
+			if (obj != NULL)
+				(*env)->Throw(env, obj);
+		}
+	}
+	return true;
+}
+
+JNIEXPORT jstring JNICALL Java_jtux_UUtil_strerror(JNIEnv *env, jclass obj,
+  jint errnum)
+{
+	JSTR_RETURN(strerror(errnum));
+}
+
+JNIEXPORT void JNICALL Java_jtux_UUtil_check_1type_1sizes(JNIEnv *env, jclass obj)
+{
+	bool ok = true;
+	/*
+		All assumptions about suitability of Java primitive types for POSIX/SUS types
+		must be tested here.
+	*/
+	if (sizeof(jlong) < sizeof(long)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(long)\n");
+	}
+	if (sizeof(jlong) < sizeof(void *)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(void *)\n");
+	}
+	if (sizeof(jint) < sizeof(int)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(int)\n");
+	}
+	if (sizeof(jshort) < sizeof(short)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jshort) < sizeof(short)\n");
+	}
+	if (sizeof(jlong) < sizeof(clock_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(clock_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(gid_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(gid_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(pid_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(pid_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(uid_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(uid_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(rlim_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(rlim_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(time_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(time_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(suseconds_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(suseconds_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(useconds_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(useconds_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(off_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(off_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(fsfilcnt_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(fsfilcnt_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(fsblkcnt_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(fsblkcnt_t)\n");
+	}
+	if (sizeof(jint) < sizeof(size_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(size_t)\n");
+	}
+	if (sizeof(jint) < sizeof(ssize_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(ssize_t)\n");
+	}
+	if (sizeof(jint) < sizeof(mode_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(mode_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(dev_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(dev_t)\n");
+	}
+	if (sizeof(jint) < sizeof(ino_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(ino_t)\n");
+	}
+	if (sizeof(jint) < sizeof(nlink_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(nlink_t)\n");
+	}
+	if (sizeof(jint) < sizeof(blksize_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(blksize_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(blkcnt_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(blkcnt_t)\n");
+	}
+	if (sizeof(jint) < sizeof(nfds_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(nfds_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(key_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(key_t)\n");
+	}
+	if (sizeof(jint) < sizeof(msgqnum_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(msgqnum_t)\n");
+	}
+	if (sizeof(jint) < sizeof(msglen_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(msglen_t)\n");
+	}
+	if (sizeof(jlong) < sizeof(mqd_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jlong) < sizeof(mqd_t)\n");
+	}
+	if (sizeof(jint) < sizeof(socklen_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(socklen_t)\n");
+	}
+	if (sizeof(jint) < sizeof(sa_family_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(sa_family_t)\n");
+	}
+	if (sizeof(jshort) < sizeof(in_port_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jshort) < sizeof(in_port_t)\n");
+	}
+	if (sizeof(jint) < sizeof(in_addr_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(jint) < sizeof(in_addr_t)\n");
+	}
+	/*
+		Assuming C ints (not only jints) are at least 32-bits, because of the int
+		argument to field_ctoj_int.
+	*/
+	if (sizeof(int) < sizeof(in_addr_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(int) < sizeof(in_addr_t)\n");
+	}
+	if (sizeof(int) < sizeof(ino_t)) {
+		ok = false;
+		fprintf(stderr, "Type size error: sizeof(int) < sizeof(ino_t)\n");
+	}
+	if (!ok)
+		setup_throw_errno(env, ENOSYS);
+}
+
+/*
+	Very crude implementation, under the assumption that speed isn't important. Can
+	be improved in space and time.
+*/
+/* Following from macrostr.c, but our lookup is different. */
+static struct {
+	char *ms_cat;
+	intptr_t ms_code;
+	char *ms_macro;
+	char *ms_desc;
+} macrostr_db[] = {
+#include "include/macrostr.incl"
+	{ NULL, 0, NULL, NULL}
+};
+
+JNIEXPORT jlong JNICALL Java_jtux_UUtil_GetSymbol(JNIEnv *env, jclass obj,
+  jstring category, jstring symbol)
+{
+	JSTR_GET_DECL(category_c, category)
+	JSTR_GET_DECL(symbol_c, symbol)
+	bool found = false;
+	long val;
+	int i;
+
+	JSTR_NULLTEST_V(category_c, -1)
+	JSTR_NULLTEST_V(symbol_c, -1)
+	for (i = 0; macrostr_db[i].ms_cat != NULL; i++)
+		if (strcmp(macrostr_db[i].ms_cat, category_c) == 0 &&
+		  strcmp(macrostr_db[i].ms_macro, symbol_c) == 0) {
+			val = macrostr_db[i].ms_code;
+			found = true;
+			break;
+		}
+	JSTR_REL(category_c, category)
+	JSTR_REL(symbol_c, symbol)
+	if (!found)
+		return 0;
+	return val;
+}
+
+JNIEXPORT jstring JNICALL Java_jtux_UUtil_GetSymbolStr(JNIEnv *env, jclass obj, jstring category,
+  jint code)
+{
+	JSTR_GET_DECL(category_c, category)
+	int i;
+	char *s = NULL;
+
+	JSTR_NULLTEST_V(category_c, NULL)
+	for (i = 0; macrostr_db[i].ms_cat != NULL; i++)
+		if (strcmp(macrostr_db[i].ms_cat, category_c) == 0 &&
+		  macrostr_db[i].ms_code == code) {
+			s = macrostr_db[i].ms_macro;
+			break;
+		}
+	JSTR_REL(category_c, category)
+	JSTR_RETURN(s);
+}
+
+/*
+	Following functions taking a jclass check it against NULL, so OK for
+	argument to be:
+
+		(*env)->FindClass(env, classname)
+
+	if the overhead of calling FindClass each time is acceptable.
+*/
+
+bool field_ctoj_long(JNIEnv *env, jclass cls, const char *field, jobject obj, long n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "J")) == NULL)
+		return false;
+	(*env)->SetLongField(env, obj, fid, n);
+	return true;
+}
+
+bool field_ctoj_int(JNIEnv *env, jclass cls, const char *field, jobject obj, int n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "I")) == NULL)
+		return false;
+	(*env)->SetIntField(env, obj, fid, n);
+	return true;
+}
+
+bool field_ctoj_boolean(JNIEnv *env, jclass cls, const char *field, jobject obj, int n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "Z")) == NULL)
+		return false;
+	(*env)->SetBooleanField(env, obj, fid, n);
+	return true;
+}
+
+bool field_ctoj_short(JNIEnv *env, jclass cls, const char *field, jobject obj, short n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "S")) == NULL)
+		return false;
+	(*env)->SetShortField(env, obj, fid, n);
+	return true;
+}
+
+bool field_ctoj_object(JNIEnv *env, jclass cls, const char *field, const char *sig, jobject obj,
+  jobject fobj)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, sig)) == NULL)
+		return false;
+	(*env)->SetObjectField(env, obj, fid, fobj);
+	return true;
+}
+
+bool field_ctoj_string(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  const char *s)
+{
+	jfieldID fid;
+	jstring js;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "Ljava/lang/String;")) == NULL)
+		return false;
+	if ((js = (*env)->NewStringUTF(env, s == NULL ? "" : s)) == NULL)
+		return false;
+	(*env)->SetObjectField(env, obj, fid, js);
+	return true;
+}
+
+bool field_jtoc_long(JNIEnv *env, jclass cls, const char *field, jobject obj, long *n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "J")) == NULL)
+		return false;
+	*n = (*env)->GetLongField(env, obj, fid);
+	return true;
+}
+
+bool field_jtoc_int(JNIEnv *env, jclass cls, const char *field, jobject obj, int *n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "I")) == NULL)
+		return false;
+	*n = (*env)->GetIntField(env, obj, fid);
+	return true;
+}
+
+bool field_jtoc_boolean(JNIEnv *env, jclass cls, const char *field, jobject obj, int *n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "Z")) == NULL)
+		return false;
+	*n = (*env)->GetBooleanField(env, obj, fid);
+	return true;
+}
+
+bool field_jtoc_short(JNIEnv *env, jclass cls, const char *field, jobject obj, short *n)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "S")) == NULL)
+		return false;
+	*n = (*env)->GetShortField(env, obj, fid);
+	return true;
+}
+
+bool field_jtoc_bytearray(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  void **ptr, jbyteArray *ba)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "[B")) == NULL)
+		return false;
+	if ((*ba = (*env)->GetObjectField(env, obj, fid)) == NULL)
+		return false;
+	*ptr = (*env)->GetByteArrayElements(env, *ba, NULL);
+	return true;
+}
+
+void field_jtoc_bytearray_release(JNIEnv *env, jbyteArray ba, void *p)
+{
+	if (ba != NULL && p != NULL)
+		(*env)->ReleaseByteArrayElements(env, ba, p, 0);
+}
+
+void field_jtoc_bytearray_release_nocopy(JNIEnv *env, jbyteArray ba, void *p)
+{
+	if (ba != NULL && p != NULL)
+		(*env)->ReleaseByteArrayElements(env, ba, p, JNI_ABORT);
+}
+
+bool field_jtoc_object(JNIEnv *env, jclass cls, const char *field, const char *sig,
+  jobject obj, jobject *fobj)
+{
+	jfieldID fid;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, sig)) == NULL)
+		return false;
+	*fobj = (*env)->GetObjectField(env, obj, fid);
+	return true;
+}
+
+bool field_jtoc_string(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  char *buf, size_t bufsize)
+{
+	jfieldID fid;
+	jstring str;
+	const jbyte *str_c;
+
+	if (cls == NULL)
+		return false;
+	if ((fid = (*env)->GetFieldID(env, cls, field, "Ljava/lang/String;")) == NULL)
+		return false;
+	if ((str = (*env)->GetObjectField(env, obj, fid)) == NULL)
+		return false;
+	if ((str_c = (*env)->GetStringUTFChars(env, str, NULL)) == NULL)
+		return false;
+	strncpy(buf, str_c, bufsize - 1);
+	buf[bufsize - 1] = '\0';
+	(*env)->ReleaseStringUTFChars(env, str, str_c);
+	return true;
+}
+
+/*
+	Assumption is that next three functions are seldom used, so no attempt to
+	cache class or method ID.
+*/
+
+bool string_buffer_set(JNIEnv *env, jobject sb, const char *s)
+{
+	jclass Utilclass = (*env)->FindClass(env, "jtux/UUtil");
+	jmethodID mid;
+
+	if (Utilclass == NULL)
+		return false;
+	if ((mid = (*env)->GetStaticMethodID(env, Utilclass, "StringBufferSet",
+	  "(Ljava/lang/StringBuffer;Ljava/lang/String;)V")) == NULL)
+		return false;
+	(*env)->CallStaticVoidMethod(env, Utilclass, mid, sb, (*env)->NewStringUTF(env, s));
+	return (*env)->ExceptionCheck(env) == 0;
+}
+
+/*
+	Caller should not release if returns NULL.
+*/
+const char *string_buffer_get(JNIEnv *env, jobject sb, jstring *obj_str)
+{
+	jclass Utilclass = (*env)->FindClass(env, "jtux/UUtil");
+	jmethodID mid;
+
+	if (Utilclass == NULL)
+		return NULL;
+	if ((mid = (*env)->GetStaticMethodID(env, Utilclass, "StringBufferGet",
+	  "(Ljava/lang/StringBuffer;)Ljava/lang/String;")) == NULL)
+		return NULL;
+	*obj_str = (*env)->CallStaticObjectMethod(env, Utilclass, mid, sb);
+	if ((*env)->ExceptionCheck(env))
+		return NULL; // caller should not release
+	return (*env)->GetStringUTFChars(env, *obj_str, NULL);
+}
+
+void string_buffer_release(JNIEnv *env, jstring obj_string, const char *s)
+{
+	(*env)->ReleaseStringUTFChars(env, obj_string, s);
+}
+
+jbyte *get_sigset(JNIEnv *env, jobject obj, jbyteArray *ba)
+{
+	jclass cls = (*env)->FindClass(env, "jtux/UProcess$sigset_t");
+	jfieldID fid;
+
+	if (cls == NULL || obj == NULL)
+		return NULL;
+	if ((fid = (*env)->GetFieldID(env, cls, "set", "[B")) == NULL)
+		return NULL;
+	if ((*ba = (*env)->GetObjectField(env, obj, fid)) == NULL)
+		return NULL;
+	return (*env)->GetByteArrayElements(env, *ba, NULL);
+}
+
+void release_sigset(JNIEnv *env, jbyteArray ba, jbyte *p)
+{
+	// Always copy back, even though for sigismember we don't have to
+	if (ba != NULL && p != NULL)
+		(*env)->ReleaseByteArrayElements(env, ba, p, 0);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UUtil_jaddr_1to_1seg(JNIEnv *env, jclass obj,
+  jlong addr, jbyteArray data, jint datasize)
+{
+	void *p;
+
+	if ((p = (*env)->GetByteArrayElements(env, data, NULL)) == NULL)
+		return;
+	memcpy((void *)(intptr_t)addr, p, datasize);
+	(*env)->ReleaseByteArrayElements(env, data, p, JNI_ABORT);
+}
+
+JNIEXPORT void JNICALL Java_jtux_UUtil_jaddr_1from_1seg(JNIEnv *env, jclass obj,
+  jlong addr, jbyteArray data, jint datasize)
+{
+	void *p;
+
+	if ((p = (*env)->GetByteArrayElements(env, data, NULL)) == NULL)
+		return;
+	memcpy(p, (void *)(intptr_t)addr, datasize);
+	(*env)->ReleaseByteArrayElements(env, data, p, 0);
+}
+
+bool get_IntHolder_int(JNIEnv *env, jobject obj_ih, int *v)
+{
+	return field_jtoc_int(env, (*env)->FindClass(env, "jtux/UUtil$IntHolder"),
+	  "value", obj_ih, v);
+}
+
+bool set_IntHolder_int(JNIEnv *env, jobject obj_ih, int v)
+{
+	return field_ctoj_int(env, (*env)->FindClass(env, "jtux/UUtil$IntHolder"),
+	  "value", obj_ih, v);
+}
+
+struct iovec *iovec_jtoc(JNIEnv *env, jobject iov, int iovcnt, jbyteArray **ba)
+{
+	struct iovec *v;
+	int i;
+	jclass cls = (*env)->FindClass(env, "jtux/UFile$s_iovec");
+
+	JTHROW_null(v = malloc(iovcnt * sizeof(struct iovec)))
+	if (v == NULL)
+		return NULL;
+	JTHROW_null(*ba = malloc(iovcnt * sizeof(jbyteArray)))
+	if (*ba == NULL) {
+		free(v);
+		return NULL;
+	}
+	for (i = 0; i < iovcnt; i++) {
+		jobject v_obj = (*env)->GetObjectArrayElement(env, iov, i);
+
+		if (v_obj == NULL) {
+			free(v);
+			free(*ba);
+			return NULL;
+		}
+		if (!field_jtoc_bytearray(env, cls, "iov_base", v_obj, &v[i].iov_base,
+		  &(*ba)[i])) {
+			free(v);
+			free(*ba);
+			return NULL;
+		}
+		if (!field_jtoc_int(env, cls, "iov_len", v_obj, &v[i].iov_len)) {
+			free(v);
+			free(*ba);
+			return NULL;
+		}
+	}
+	return v;
+}
+
+void iovec_jtoc_release_nocopy(JNIEnv *env, struct iovec *v, int iovcnt, jbyteArray *ba)
+{
+	int i;
+
+	for (i = 0; i < iovcnt; i++)
+		field_jtoc_bytearray_release_nocopy(env, ba[i], v[i].iov_base);
+	free(v);
+	free(ba);
+}
+
+void iovec_jtoc_release(JNIEnv *env, struct iovec *v, int iovcnt, jbyteArray *ba)
+{
+	int i;
+
+	for (i = 0; i < iovcnt; i++)
+		field_jtoc_bytearray_release(env, ba[i], v[i].iov_base);
+	free(v);
+	free(ba);
+}
diff --git a/jtux_util.h b/jtux_util.h
new file mode 100755
index 0000000..96a5e8a
--- /dev/null
+++ b/jtux_util.h
@@ -0,0 +1,44 @@
+#ifndef _JTUX_UTIL_H_
+#define _JTUX_UTIL_H_
+
+#include <jni.h>
+
+void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg);
+bool setup_throw_errno(JNIEnv *env, int code);
+bool setup_throw_errno_type(JNIEnv *env, int code, int type);
+
+bool field_ctoj_long(JNIEnv *env, jclass cls, const char *field, jobject obj, long n);
+bool field_ctoj_int(JNIEnv *env, jclass cls, const char *field, jobject obj, int n);
+bool field_ctoj_boolean(JNIEnv *env, jclass cls, const char *field, jobject obj, int n);
+bool field_ctoj_short(JNIEnv *env, jclass cls, const char *field, jobject obj, short n);
+bool field_ctoj_object(JNIEnv *env, jclass cls, const char *field, const char *sig, jobject obj,
+  jobject fobj);
+bool field_ctoj_string(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  const char *s);
+bool field_jtoc_long(JNIEnv *env, jclass cls, const char *field, jobject obj, long *n);
+bool field_jtoc_int(JNIEnv *env, jclass cls, const char *field, jobject obj, int *n);
+bool field_jtoc_boolean(JNIEnv *env, jclass cls, const char *field, jobject obj, int *n);
+bool field_jtoc_short(JNIEnv *env, jclass cls, const char *field, jobject obj, short *n);
+bool field_jtoc_bytearray(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  void **ptr, jbyteArray *ba);
+void field_jtoc_bytearray_release_nocopy(JNIEnv *env, jbyteArray ba, void *p);
+void field_jtoc_bytearray_release(JNIEnv *env, jbyteArray ba, void *p);
+bool field_jtoc_object(JNIEnv *env, jclass cls, const char *field, const char *sig,
+  jobject obj, jobject *fobj);
+bool field_jtoc_string(JNIEnv *env, jclass cls, const char *field, jobject obj,
+  char *buf, size_t bufsize);
+bool string_buffer_set(JNIEnv *env, jobject sb, const char *s);
+const char *string_buffer_get(JNIEnv *env, jobject sb, jstring *obj_str);
+void string_buffer_release(JNIEnv *env, jstring obj_string, const char *s);
+
+jbyte *get_sigset(JNIEnv *env, jobject obj, jbyteArray *ba);
+void release_sigset(JNIEnv *env, jbyteArray ba, jbyte *p);
+
+bool get_IntHolder_int(JNIEnv *env, jobject obj_ih, int *v);
+bool set_IntHolder_int(JNIEnv *env, jobject obj_ih, int v);
+
+struct iovec *iovec_jtoc(JNIEnv *env, jobject iov, int iovcnt, jbyteArray **ba);
+void iovec_jtoc_release_nocopy(JNIEnv *env, struct iovec *v, int iovcnt, jbyteArray *ba);
+void iovec_jtoc_release(JNIEnv *env, struct iovec *v, int iovcnt, jbyteArray *ba);
+
+#endif /* _JTUX_UTIL_H_ */