/*
	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
}
