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