libcore_io_Linux.cpp revision a20cc6fca30d18e05db67ceeb0403b7b58ffd364
1ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes/* 2ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Copyright (C) 2011 The Android Open Source Project 3ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * 4ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * you may not use this file except in compliance with the License. 6ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * You may obtain a copy of the License at 7ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * 8ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * 10ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * See the License for the specific language governing permissions and 14ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * limitations under the License. 15ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes */ 16ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes 17ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes#define LOG_TAG "Posix" 18ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes 19ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes#include "JNIHelp.h" 20ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes#include "JniConstants.h" 21ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes#include "JniException.h" 220f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes#include "ScopedPrimitiveArray.h" 23ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes#include "ScopedUtfChars.h" 24ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes#include "toStringArray.h" 25ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes 26ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes#include <errno.h> 270ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes#include <fcntl.h> 28ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes#include <stdlib.h> 297e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes#include <sys/mman.h> 3047cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes#include <sys/stat.h> 310ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes#include <sys/stat.h> 320ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes#include <sys/types.h> 330ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes#include <unistd.h> 34ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes 357e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughesstatic void throwErrnoException(JNIEnv* env, const char* name) { 367e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes int errnum = errno; 377e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes 38ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes jthrowable cause = NULL; 39ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes if (env->ExceptionCheck()) { 40ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes cause = env->ExceptionOccurred(); 41ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes env->ExceptionClear(); 42ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes } 43ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes 44f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes ScopedLocalRef<jstring> javaName(env, env->NewStringUTF(name)); 45f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes if (javaName.get() == NULL) { 46f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes // Not really much we can do here. We're probably dead in the water, 47f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes // but let's try to stumble on... 48f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes env->ExceptionClear(); 49f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes } 50f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes 51ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes jobject exception; 52ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes if (cause != NULL) { 53f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes static jmethodID ctor = env->GetMethodID(JniConstants::errnoExceptionClass, "<init>", 54f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes "(Ljava/lang/String;ILjava/lang/Throwable;)V"); 55f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes exception = env->NewObject(JniConstants::errnoExceptionClass, ctor, 56f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes javaName.get(), errnum, cause); 57ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes } else { 58f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes static jmethodID ctor = env->GetMethodID(JniConstants::errnoExceptionClass, "<init>", 59f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes "(Ljava/lang/String;I)V"); 60f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes exception = env->NewObject(JniConstants::errnoExceptionClass, ctor, javaName.get(), errnum); 61ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes } 62ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes env->Throw(reinterpret_cast<jthrowable>(exception)); 63dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes} 64dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes 65dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughestemplate <typename rc_t> 667e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughesstatic rc_t throwIfMinusOne(JNIEnv* env, const char* name, rc_t rc) { 67dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes if (rc == rc_t(-1)) { 687e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwErrnoException(env, name); 69dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes } 70dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes return rc; 7147cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes} 7247cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes 7347cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughesstatic jobject makeStructStat(JNIEnv* env, const struct stat& sb) { 7447cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes static jmethodID ctor = env->GetMethodID(JniConstants::structStatClass, "<init>", 7547cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes "(JJIJIIJJJJJJJ)V"); 7647cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return env->NewObject(JniConstants::structStatClass, ctor, 7747cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes jlong(sb.st_dev), jlong(sb.st_ino), jint(sb.st_mode), jlong(sb.st_nlink), 7847cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes jint(sb.st_uid), jint(sb.st_gid), jlong(sb.st_rdev), jlong(sb.st_size), 7947cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes jlong(sb.st_atime), jlong(sb.st_mtime), jlong(sb.st_ctime), 8047cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes jlong(sb.st_blksize), jlong(sb.st_blocks)); 8147cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes} 8247cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes 8347cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughesstatic jobject doStat(JNIEnv* env, jstring javaPath, bool isLstat) { 8447cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes ScopedUtfChars path(env, javaPath); 8547cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes if (path.c_str() == NULL) { 8647cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return NULL; 8747cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes } 8847cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes struct stat sb; 8947cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes int rc = isLstat ? TEMP_FAILURE_RETRY(lstat(path.c_str(), &sb)) 9047cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes : TEMP_FAILURE_RETRY(stat(path.c_str(), &sb)); 91dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes if (rc == -1) { 927e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwErrnoException(env, isLstat ? "lstat" : "stat"); 9347cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return NULL; 9447cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes } 9547cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return makeStructStat(env, sb); 96ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes} 97ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes 98ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughesstatic jboolean Posix_access(JNIEnv* env, jobject, jstring javaPath, jint mode) { 99ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes ScopedUtfChars path(env, javaPath); 100ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes if (path.c_str() == NULL) { 101ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes return JNI_FALSE; 102ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes } 10347cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes int rc = TEMP_FAILURE_RETRY(access(path.c_str(), mode)); 104dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes if (rc == -1) { 1057e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwErrnoException(env, "access"); 106dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes } 107ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes return (rc == 0); 108ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes} 109ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes 110ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughesstatic jobjectArray Posix_environ(JNIEnv* env, jobject) { 111ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes extern char** environ; // Standard, but not in any header file. 112ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes return toStringArray(env, environ); 113ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes} 114ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes 11552724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughesstatic void Posix_fdatasync(JNIEnv* env, jobject, jobject javaFd) { 11652724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes int fd = jniGetFDFromFileDescriptor(env, javaFd); 1177e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwIfMinusOne(env, "fdatasync", TEMP_FAILURE_RETRY(fdatasync(fd))); 11852724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes} 11952724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes 12047cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughesstatic jobject Posix_fstat(JNIEnv* env, jobject, jobject javaFd) { 12147cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes int fd = jniGetFDFromFileDescriptor(env, javaFd); 12247cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes struct stat sb; 12347cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes int rc = TEMP_FAILURE_RETRY(fstat(fd, &sb)); 124dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes if (rc == -1) { 1257e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwErrnoException(env, "fstat"); 12647cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return NULL; 12747cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes } 12847cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return makeStructStat(env, sb); 12947cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes} 13047cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes 13152724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughesstatic void Posix_fsync(JNIEnv* env, jobject, jobject javaFd) { 13252724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes int fd = jniGetFDFromFileDescriptor(env, javaFd); 1337e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwIfMinusOne(env, "fsync", TEMP_FAILURE_RETRY(fsync(fd))); 134f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes} 135f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes 136f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughesstatic void Posix_ftruncate(JNIEnv* env, jobject, jobject javaFd, jlong length) { 137f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes int fd = jniGetFDFromFileDescriptor(env, javaFd); 1387e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwIfMinusOne(env, "ftruncate", TEMP_FAILURE_RETRY(ftruncate64(fd, length))); 13952724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes} 14052724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes 141ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughesstatic jstring Posix_getenv(JNIEnv* env, jobject, jstring javaName) { 142ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes ScopedUtfChars name(env, javaName); 143ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes if (name.c_str() == NULL) { 144ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes return NULL; 145ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes } 146ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes return env->NewStringUTF(getenv(name.c_str())); 147ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes} 148ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes 1499a3f363523000704205df288f8b6f2f48c0d8563Elliott Hughesstatic jboolean Posix_isatty(JNIEnv* env, jobject, jobject javaFd) { 1509a3f363523000704205df288f8b6f2f48c0d8563Elliott Hughes int fd = jniGetFDFromFileDescriptor(env, javaFd); 1519a3f363523000704205df288f8b6f2f48c0d8563Elliott Hughes return TEMP_FAILURE_RETRY(isatty(fd)) == 0; 1529a3f363523000704205df288f8b6f2f48c0d8563Elliott Hughes} 1539a3f363523000704205df288f8b6f2f48c0d8563Elliott Hughes 154dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughesstatic jlong Posix_lseek(JNIEnv* env, jobject, jobject javaFd, jlong offset, jint whence) { 155dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes int fd = jniGetFDFromFileDescriptor(env, javaFd); 1567e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes return throwIfMinusOne(env, "lseek", TEMP_FAILURE_RETRY(lseek64(fd, offset, whence))); 157dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes} 158dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes 15947cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughesstatic jobject Posix_lstat(JNIEnv* env, jobject, jstring javaPath) { 16047cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return doStat(env, javaPath, true); 16147cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes} 16247cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes 1630f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughesstatic void Posix_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) { 1640f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes ScopedByteArrayRW vector(env, javaVector); 1650f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes if (vector.get() == NULL) { 1660f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes return; 1670f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes } 1680f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address)); 1690f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes unsigned char* vec = reinterpret_cast<unsigned char*>(vector.get()); 1700f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes throwIfMinusOne(env, "mincore", TEMP_FAILURE_RETRY(mincore(ptr, byteCount, vec))); 1710f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes} 1720f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes 1737e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughesstatic void Posix_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) { 1747e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address)); 1757e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes throwIfMinusOne(env, "mlock", TEMP_FAILURE_RETRY(mlock(ptr, byteCount))); 1767e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes} 1777e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes 1787e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughesstatic jlong Posix_mmap(JNIEnv* env, jobject, jlong address, jlong byteCount, jint prot, jint flags, jobject javaFd, jlong offset) { 1797e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes int fd = jniGetFDFromFileDescriptor(env, javaFd); 1807e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes void* suggestedPtr = reinterpret_cast<void*>(static_cast<uintptr_t>(address)); 1817e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes void* ptr = mmap(suggestedPtr, byteCount, prot, flags, fd, offset); 1827e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes if (ptr == MAP_FAILED) { 1837e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwErrnoException(env, "mmap"); 1847e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes } 1857e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr)); 1867e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes} 1877e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes 1887e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughesstatic void Posix_msync(JNIEnv* env, jobject, jlong address, jlong byteCount, jint flags) { 1897e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address)); 1907e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwIfMinusOne(env, "msync", TEMP_FAILURE_RETRY(msync(ptr, byteCount, flags))); 1917e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes} 1927e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes 1937e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughesstatic void Posix_munlock(JNIEnv* env, jobject, jlong address, jlong byteCount) { 1947e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address)); 1957e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes throwIfMinusOne(env, "munlock", TEMP_FAILURE_RETRY(munlock(ptr, byteCount))); 1967e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes} 1977e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes 1987e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughesstatic void Posix_munmap(JNIEnv* env, jobject, jlong address, jlong byteCount) { 1997e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address)); 2007e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwIfMinusOne(env, "munmap", TEMP_FAILURE_RETRY(munmap(ptr, byteCount))); 2017e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes} 2027e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes 2030ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughesstatic jobject Posix_open(JNIEnv* env, jobject, jstring javaPath, jint flags, jint mode) { 2040ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes ScopedUtfChars path(env, javaPath); 2050ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes if (path.c_str() == NULL) { 2060ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes return NULL; 2070ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes } 2080ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes int fd = throwIfMinusOne(env, "open", TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode))); 2090ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL; 2100ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes} 2110ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes 212a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughesstatic void Posix_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) { 213a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes ScopedUtfChars oldPath(env, javaOldPath); 214a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes if (oldPath.c_str() == NULL) { 215a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes return; 216a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes } 217a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes ScopedUtfChars newPath(env, javaNewPath); 218a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes if (newPath.c_str() == NULL) { 219a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes return; 220a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes } 221a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes throwIfMinusOne(env, "rename", TEMP_FAILURE_RETRY(rename(oldPath.c_str(), newPath.c_str()))); 222a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes} 223a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes 22447cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughesstatic jobject Posix_stat(JNIEnv* env, jobject, jstring javaPath) { 22547cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes return doStat(env, javaPath, false); 22647cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes} 22747cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes 228ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughesstatic jstring Posix_strerror(JNIEnv* env, jobject, jint errnum) { 22952724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes char buffer[BUFSIZ]; 230ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes const char* message = jniStrError(errnum, buffer, sizeof(buffer)); 231ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes return env->NewStringUTF(message); 232ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes} 233ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes 234a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughesstatic void Posix_symlink(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) { 235a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes ScopedUtfChars oldPath(env, javaOldPath); 236a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes if (oldPath.c_str() == NULL) { 237a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes return; 238a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes } 239a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes ScopedUtfChars newPath(env, javaNewPath); 240a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes if (newPath.c_str() == NULL) { 241a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes return; 242a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes } 243a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes throwIfMinusOne(env, "symlink", TEMP_FAILURE_RETRY(symlink(oldPath.c_str(), newPath.c_str()))); 244a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes} 245a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes 2466fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughesstatic jlong Posix_sysconf(JNIEnv* env, jobject, jint name) { 2476fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes // Since -1 is a valid result from sysconf(3), detecting failure is a little more awkward. 2486fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes errno = 0; 2496fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes long result = sysconf(name); 2506fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes if (result == -1L && errno == EINVAL) { 2517e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes throwErrnoException(env, "sysconf"); 2526fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes } 2536fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes return result; 2546fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes} 2556fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes 256ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughesstatic JNINativeMethod gMethods[] = { 257ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"), 258ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes NATIVE_METHOD(Posix, environ, "()[Ljava/lang/String;"), 25952724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes NATIVE_METHOD(Posix, fdatasync, "(Ljava/io/FileDescriptor;)V"), 26047cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes NATIVE_METHOD(Posix, fstat, "(Ljava/io/FileDescriptor;)Llibcore/io/StructStat;"), 26152724d3ebd4ccaaa4b9f5576e329d4272cde8ea9Elliott Hughes NATIVE_METHOD(Posix, fsync, "(Ljava/io/FileDescriptor;)V"), 262f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes NATIVE_METHOD(Posix, ftruncate, "(Ljava/io/FileDescriptor;J)V"), 263ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes NATIVE_METHOD(Posix, getenv, "(Ljava/lang/String;)Ljava/lang/String;"), 2649a3f363523000704205df288f8b6f2f48c0d8563Elliott Hughes NATIVE_METHOD(Posix, isatty, "(Ljava/io/FileDescriptor;)Z"), 265dedaccdfa07c370a58cba08b096133ad9eec0ec3Elliott Hughes NATIVE_METHOD(Posix, lseek, "(Ljava/io/FileDescriptor;JI)J"), 26647cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes NATIVE_METHOD(Posix, lstat, "(Ljava/lang/String;)Llibcore/io/StructStat;"), 2670f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughes NATIVE_METHOD(Posix, mincore, "(JJ[B)V"), 2687e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes NATIVE_METHOD(Posix, mlock, "(JJ)V"), 2697e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes NATIVE_METHOD(Posix, mmap, "(JJIILjava/io/FileDescriptor;J)J"), 2707e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes NATIVE_METHOD(Posix, msync, "(JJI)V"), 2717e13c0f05ac9e7c55682d10e953dd4cbd5e6107cElliott Hughes NATIVE_METHOD(Posix, munlock, "(JJ)V"), 2727e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes NATIVE_METHOD(Posix, munmap, "(JJ)V"), 2730ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes NATIVE_METHOD(Posix, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"), 274a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"), 27547cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes NATIVE_METHOD(Posix, stat, "(Ljava/lang/String;)Llibcore/io/StructStat;"), 276ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes NATIVE_METHOD(Posix, strerror, "(I)Ljava/lang/String;"), 277a20cc6fca30d18e05db67ceeb0403b7b58ffd364Elliott Hughes NATIVE_METHOD(Posix, symlink, "(Ljava/lang/String;Ljava/lang/String;)V"), 2786fc1a0e1e68dc2e0d12341548e58fa7f1c5dafc4Elliott Hughes NATIVE_METHOD(Posix, sysconf, "(I)J"), 279ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes}; 280ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughesint register_libcore_io_Posix(JNIEnv* env) { 281ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes return jniRegisterNativeMethods(env, "libcore/io/Posix", gMethods, NELEM(gMethods)); 282ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes} 283