import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-/**
- * This is the portable implementation of the file system interface.
- *
- */
class OSFileSystem implements IFileSystem {
private static final OSFileSystem singleton = new OSFileSystem();
}
private OSFileSystem() {
- super();
}
private final void validateLockArgs(int type, long start, long length) {
// Start position
if (start < 0) {
- throw new IllegalArgumentException(
- "Lock start position must be non-negative");
+ throw new IllegalArgumentException("start < 0");
}
// Length of lock stretch
if (length < 0) {
- throw new IllegalArgumentException(
- "Lock length must be non-negative");
+ throw new IllegalArgumentException("length < 0");
}
}
- private native int lockImpl(int fileDescriptor, long start, long length,
- int type, boolean wait);
+ private native int lockImpl(int fd, long start, long length, int type, boolean wait);
/**
* Returns the granularity for virtual memory allocation.
public native long length(int fd);
- public boolean lock(int fileDescriptor, long start, long length, int type,
- boolean waitFlag) throws IOException {
+ public boolean lock(int fd, long start, long length, int type, boolean waitFlag)
+ throws IOException {
// Validate arguments
validateLockArgs(type, start, length);
- int result = lockImpl(fileDescriptor, start, length, type, waitFlag);
+ int result = lockImpl(fd, start, length, type, waitFlag);
return result != -1;
}
- // BEGIN android-changed
- private native void unlockImpl(int fileDescriptor, long start, long length) throws IOException;
+ private native void unlockImpl(int fd, long start, long length) throws IOException;
- public void unlock(int fileDescriptor, long start, long length)
- throws IOException {
+ public void unlock(int fd, long start, long length) throws IOException {
// Validate arguments
validateLockArgs(IFileSystem.SHARED_LOCK_TYPE, start, length);
- unlockImpl(fileDescriptor, start, length);
+ unlockImpl(fd, start, length);
}
- public native void fflush(int fileDescriptor, boolean metadata) throws IOException;
+ public native void fflush(int fd, boolean metadata) throws IOException;
/*
* File position seeking.
/*
* Direct read/write APIs work on addresses.
*/
- public native long readDirect(int fileDescriptor, int address, int offset, int length);
+ public native long readDirect(int fd, int address, int offset, int length);
- public native long writeDirect(int fileDescriptor, int address, int offset, int length)
- throws IOException;
+ public native long writeDirect(int fd, int address, int offset, int length);
/*
* Indirect read/writes work on byte[]'s
*/
- private native long readImpl(int fileDescriptor, byte[] bytes, int offset,
- int length) throws IOException;
+ public native long read(int fd, byte[] bytes, int offset, int length) throws IOException;
- public long read(int fileDescriptor, byte[] bytes, int offset, int length)
- throws IOException {
- if (bytes == null) {
- throw new NullPointerException();
- }
- return readImpl(fileDescriptor, bytes, offset, length);
- }
-
- private native long writeImpl(int fileDescriptor, byte[] bytes,
- int offset, int length) throws IOException;
-
- public long write(int fileDescriptor, byte[] bytes, int offset, int length)
- throws IOException {
- if (bytes == null) {
- throw new NullPointerException();
- }
- return writeImpl(fileDescriptor, bytes, offset, length);
- }
- // END android-changed
+ public native long write(int fd, byte[] bytes, int offset, int length) throws IOException;
/*
* Scatter/gather calls.
*/
- public native long readv(int fileDescriptor, int[] addresses,
- int[] offsets, int[] lengths, int size) throws IOException;
-
- public native long writev(int fileDescriptor, int[] addresses, int[] offsets,
- int[] lengths, int size) throws IOException;
+ public native long readv(int fd, int[] addresses, int[] offsets, int[] lengths, int size)
+ throws IOException;
- // BEGIN android-changed
- public native void close(int fileDescriptor) throws IOException;
+ public native long writev(int fd, int[] addresses, int[] offsets, int[] lengths, int size)
+ throws IOException;
- public native void truncate(int fileDescriptor, long size) throws IOException;
- // END android-changed
+ public native void close(int fd) throws IOException;
- public int open(byte[] utfPathBytes, int mode) throws FileNotFoundException {
- if (utfPathBytes == null) {
- throw new NullPointerException();
- }
- return openImpl(utfPathBytes, mode);
- }
+ public native void truncate(int fd, long size) throws IOException;
- private native int openImpl(byte[] fileName, int mode);
+ public native int open(byte[] utfPathBytes, int mode) throws FileNotFoundException;
- // BEGIN android-changed
public native long transfer(int fd, FileDescriptor sd, long offset, long count)
throws IOException;
- // END android-changed
-
- // BEGIN android-deleted
- // public long ttyAvailable() throws IOException {
- // long nChar = ttyAvailableImpl();
- // if (nChar < 0) {
- // throw new IOException();
- // }
- // return nChar;
- // }
- //
- // private native long ttyAvailableImpl();
- // END android-deleted
-
- // BEGIN android-deleted
- // public long ttyRead(byte[] bytes, int offset, int length) throws IOException {
- // if (bytes == null) {
- // throw new NullPointerException();
- // }
- // return ttyReadImpl(bytes, offset, length);
- // }
- // private native long ttyReadImpl(byte[] bytes, int offset, int length) throws IOException;
- // END android-deleted
-
- // BEGIN android-added
+
public native int ioctlAvailable(FileDescriptor fileDescriptor) throws IOException;
- // END android-added
}
*/
#include <sys/socket.h>
#include <sys/types.h>
-static inline ssize_t sendfile(int out_fd, int in_fd, off_t *offset,
- size_t count) {
+static inline ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
off_t len = count;
int result = sendfile(in_fd, out_fd, *offset, &len, NULL, 0);
if (result < 0) {
return lock;
}
-static jint harmony_io_lockImpl(JNIEnv* env, jobject, jint handle,
+static jint OSFileSystem_lockImpl(JNIEnv* env, jobject, jint fd,
jlong start, jlong length, jint typeFlag, jboolean waitFlag) {
length = translateLockLength(length);
}
int waitMode = (waitFlag) ? F_SETLKW : F_SETLK;
- return TEMP_FAILURE_RETRY(fcntl(handle, waitMode, &lock));
+ return TEMP_FAILURE_RETRY(fcntl(fd, waitMode, &lock));
}
-static void harmony_io_unlockImpl(JNIEnv* env, jobject, jint handle,
- jlong start, jlong length) {
-
+static void OSFileSystem_unlockImpl(JNIEnv* env, jobject, jint fd, jlong start, jlong length) {
length = translateLockLength(length);
if (offsetTooLarge(env, start) || offsetTooLarge(env, length)) {
return;
struct flock lock(flockFromStartAndLength(start, length));
lock.l_type = F_UNLCK;
- int rc = TEMP_FAILURE_RETRY(fcntl(handle, F_SETLKW, &lock));
+ int rc = TEMP_FAILURE_RETRY(fcntl(fd, F_SETLKW, &lock));
if (rc == -1) {
jniThrowIOException(env, errno);
}
* Returns the granularity of the starting address for virtual memory allocation.
* (It's the same as the page size.)
*/
-static jint harmony_io_getAllocGranularity(JNIEnv*, jobject) {
+static jint OSFileSystem_getAllocGranularity(JNIEnv*, jobject) {
static int allocGranularity = getpagesize();
return allocGranularity;
}
// Translate three Java int[]s to a native iovec[] for readv and writev.
static iovec* initIoVec(JNIEnv* env,
jintArray jBuffers, jintArray jOffsets, jintArray jLengths, jint size) {
- iovec* vectors = new iovec[size];
- if (vectors == NULL) {
+ UniquePtr<iovec[]> vectors(new iovec[size]);
+ if (vectors.get() == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", "native heap");
return NULL;
}
ScopedIntArrayRO buffers(env, jBuffers);
+ if (buffers.get() == NULL) {
+ return NULL;
+ }
ScopedIntArrayRO offsets(env, jOffsets);
+ if (offsets.get() == NULL) {
+ return NULL;
+ }
ScopedIntArrayRO lengths(env, jLengths);
+ if (lengths.get() == NULL) {
+ return NULL;
+ }
for (int i = 0; i < size; ++i) {
vectors[i].iov_base = reinterpret_cast<void*>(buffers[i] + offsets[i]);
vectors[i].iov_len = lengths[i];
}
- return vectors;
+ return vectors.release();
}
-static jlong harmony_io_readv(JNIEnv* env, jobject, jint fd,
+static jlong OSFileSystem_readv(JNIEnv* env, jobject, jint fd,
jintArray jBuffers, jintArray jOffsets, jintArray jLengths, jint size) {
- UniquePtr<iovec> vectors(initIoVec(env, jBuffers, jOffsets, jLengths, size));
+ UniquePtr<iovec[]> vectors(initIoVec(env, jBuffers, jOffsets, jLengths, size));
if (vectors.get() == NULL) {
return -1;
}
return result;
}
-static jlong harmony_io_writev(JNIEnv* env, jobject, jint fd,
+static jlong OSFileSystem_writev(JNIEnv* env, jobject, jint fd,
jintArray jBuffers, jintArray jOffsets, jintArray jLengths, jint size) {
- UniquePtr<iovec> vectors(initIoVec(env, jBuffers, jOffsets, jLengths, size));
+ UniquePtr<iovec[]> vectors(initIoVec(env, jBuffers, jOffsets, jLengths, size));
if (vectors.get() == NULL) {
return -1;
}
return result;
}
-static jlong harmony_io_transfer(JNIEnv* env, jobject, jint fd, jobject sd,
+static jlong OSFileSystem_transfer(JNIEnv* env, jobject, jint fd, jobject sd,
jlong offset, jlong count) {
int socket = jniGetFDFromFileDescriptor(env, sd);
return rc;
}
-static jlong harmony_io_readDirect(JNIEnv* env, jobject, jint fd,
+static jlong OSFileSystem_readDirect(JNIEnv* env, jobject, jint fd,
jint buf, jint offset, jint nbytes) {
if (nbytes == 0) {
return 0;
return rc;
}
-static jlong harmony_io_writeDirect(JNIEnv* env, jobject, jint fd,
+static jlong OSFileSystem_writeDirect(JNIEnv* env, jobject, jint fd,
jint buf, jint offset, jint nbytes) {
jbyte* src = reinterpret_cast<jbyte*>(buf + offset);
jlong rc = TEMP_FAILURE_RETRY(write(fd, src, nbytes));
return rc;
}
-static jlong harmony_io_readImpl(JNIEnv* env, jobject, jint fd,
+static jlong OSFileSystem_read(JNIEnv* env, jobject, jint fd,
jbyteArray byteArray, jint offset, jint nbytes) {
-
if (nbytes == 0) {
return 0;
}
ScopedByteArrayRW bytes(env, byteArray);
+ if (bytes.get() == NULL) {
+ return 0;
+ }
jlong rc = TEMP_FAILURE_RETRY(read(fd, bytes.get() + offset, nbytes));
if (rc == 0) {
return -1;
return rc;
}
-static jlong harmony_io_writeImpl(JNIEnv* env, jobject, jint fd,
+static jlong OSFileSystem_write(JNIEnv* env, jobject, jint fd,
jbyteArray byteArray, jint offset, jint nbytes) {
ScopedByteArrayRO bytes(env, byteArray);
+ if (bytes.get() == NULL) {
+ return 0;
+ }
jlong result = TEMP_FAILURE_RETRY(write(fd, bytes.get() + offset, nbytes));
if (result == -1) {
if (errno == EAGAIN) {
- jniThrowException(env, "java/io/InterruptedIOException",
- "Write timed out");
+ jniThrowException(env, "java/io/InterruptedIOException", "Write timed out");
} else {
jniThrowIOException(env, errno);
}
return result;
}
-static jlong harmony_io_seek(JNIEnv* env, jobject, jint fd, jlong offset,
- jint javaWhence) {
+static jlong OSFileSystem_seek(JNIEnv* env, jobject, jint fd, jlong offset, jint javaWhence) {
/* Convert whence argument */
int nativeWhence = 0;
switch (javaWhence) {
return result;
}
-static void harmony_io_fflush(JNIEnv* env, jobject, jint fd, jboolean metadataToo) {
+static void OSFileSystem_fflush(JNIEnv* env, jobject, jint fd, jboolean metadataToo) {
LOGW("fdatasync unimplemented on Android"); // http://b/2667481
int rc = fsync(fd);
// int rc = metadataToo ? fsync(fd) : fdatasync(fd);
}
}
-static jint harmony_io_close(JNIEnv* env, jobject, jint fd) {
+static jint OSFileSystem_close(JNIEnv* env, jobject, jint fd) {
jint rc = TEMP_FAILURE_RETRY(close(fd));
if (rc == -1) {
jniThrowIOException(env, errno);
return rc;
}
-static jint harmony_io_truncate(JNIEnv* env, jobject, jint fd, jlong length) {
+static jint OSFileSystem_truncate(JNIEnv* env, jobject, jint fd, jlong length) {
if (offsetTooLarge(env, length)) {
return -1;
}
return rc;
}
-static jint harmony_io_openImpl(JNIEnv* env, jobject, jbyteArray pathByteArray,
- jint jflags) {
+static jint OSFileSystem_open(JNIEnv* env, jobject, jbyteArray pathByteArray, jint jflags) {
int flags = 0;
int mode = 0;
flags = EsTranslateOpenFlags(flags);
ScopedByteArrayRO path(env, pathByteArray);
+ if (path.get() == NULL) {
+ return -1;
+ }
jint rc = TEMP_FAILURE_RETRY(open(reinterpret_cast<const char*>(&path[0]), flags, mode));
if (rc == -1) {
// Get the human-readable form of errno.
return rc;
}
-static jint harmony_io_ioctlAvailable(JNIEnv*env, jobject, jobject fileDescriptor) {
+static jint OSFileSystem_ioctlAvailable(JNIEnv*env, jobject, jobject fileDescriptor) {
/*
* On underlying platforms Android cares about (read "Linux"),
* ioctl(fd, FIONREAD, &avail) is supposed to do the following:
}
static JNINativeMethod gMethods[] = {
- { "close", "(I)V", (void*) harmony_io_close },
- { "fflush", "(IZ)V", (void*) harmony_io_fflush },
- { "getAllocGranularity","()I", (void*) harmony_io_getAllocGranularity },
- { "ioctlAvailable", "(Ljava/io/FileDescriptor;)I", (void*) harmony_io_ioctlAvailable },
+ { "close", "(I)V", (void*) OSFileSystem_close },
+ { "fflush", "(IZ)V", (void*) OSFileSystem_fflush },
+ { "getAllocGranularity", "()I", (void*) OSFileSystem_getAllocGranularity },
+ { "ioctlAvailable", "(Ljava/io/FileDescriptor;)I", (void*) OSFileSystem_ioctlAvailable },
{ "length", "(I)J", (void*) lengthImpl },
- { "lockImpl", "(IJJIZ)I", (void*) harmony_io_lockImpl },
- { "openImpl", "([BI)I", (void*) harmony_io_openImpl },
- { "readDirect", "(IIII)J", (void*) harmony_io_readDirect },
- { "readImpl", "(I[BII)J", (void*) harmony_io_readImpl },
- { "readv", "(I[I[I[II)J",(void*) harmony_io_readv },
- { "seek", "(IJI)J", (void*) harmony_io_seek },
- { "transfer", "(ILjava/io/FileDescriptor;JJ)J", (void*) harmony_io_transfer },
- { "truncate", "(IJ)V", (void*) harmony_io_truncate },
- { "unlockImpl", "(IJJ)V", (void*) harmony_io_unlockImpl },
- { "writeDirect", "(IIII)J", (void*) harmony_io_writeDirect },
- { "writeImpl", "(I[BII)J", (void*) harmony_io_writeImpl },
- { "writev", "(I[I[I[II)J",(void*) harmony_io_writev },
+ { "lockImpl", "(IJJIZ)I", (void*) OSFileSystem_lockImpl },
+ { "open", "([BI)I", (void*) OSFileSystem_open },
+ { "read", "(I[BII)J", (void*) OSFileSystem_read },
+ { "readDirect", "(IIII)J", (void*) OSFileSystem_readDirect },
+ { "readv", "(I[I[I[II)J", (void*) OSFileSystem_readv },
+ { "seek", "(IJI)J", (void*) OSFileSystem_seek },
+ { "transfer", "(ILjava/io/FileDescriptor;JJ)J", (void*) OSFileSystem_transfer },
+ { "truncate", "(IJ)V", (void*) OSFileSystem_truncate },
+ { "unlockImpl", "(IJJ)V", (void*) OSFileSystem_unlockImpl },
+ { "write", "(I[BII)J", (void*) OSFileSystem_write },
+ { "writeDirect", "(IIII)J", (void*) OSFileSystem_writeDirect },
+ { "writev", "(I[I[I[II)J", (void*) OSFileSystem_writev },
};
int register_org_apache_harmony_luni_platform_OSFileSystem(JNIEnv* env) {
return jniRegisterNativeMethods(env, "org/apache/harmony/luni/platform/OSFileSystem", gMethods,