libcore_io_Linux.cpp revision 0f746ff511162add42eeabaf14ba70ace874c6f4
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright (C) 2011 The Android Open Source Project
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define LOG_TAG "Posix"
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "JNIHelp.h"
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "JniConstants.h"
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "JniException.h"
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "ScopedPrimitiveArray.h"
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "ScopedUtfChars.h"
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "toStringArray.h"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <errno.h>
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdlib.h>
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <unistd.h>
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sys/mman.h>
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sys/stat.h>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void throwErrnoException(JNIEnv* env, const char* name) {
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int errnum = errno;
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    jthrowable cause = NULL;
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (env->ExceptionCheck()) {
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        cause = env->ExceptionOccurred();
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        env->ExceptionClear();
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    ScopedLocalRef<jstring> javaName(env, env->NewStringUTF(name));
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (javaName.get() == NULL) {
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        // Not really much we can do here. We're probably dead in the water,
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        // but let's try to stumble on...
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        env->ExceptionClear();
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    jobject exception;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (cause != NULL) {
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        static jmethodID ctor = env->GetMethodID(JniConstants::errnoExceptionClass, "<init>",
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                "(Ljava/lang/String;ILjava/lang/Throwable;)V");
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        exception = env->NewObject(JniConstants::errnoExceptionClass, ctor,
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                javaName.get(), errnum, cause);
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    } else {
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        static jmethodID ctor = env->GetMethodID(JniConstants::errnoExceptionClass, "<init>",
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                "(Ljava/lang/String;I)V");
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        exception = env->NewObject(JniConstants::errnoExceptionClass, ctor, javaName.get(), errnum);
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    env->Throw(reinterpret_cast<jthrowable>(exception));
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename rc_t>
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic rc_t throwIfMinusOne(JNIEnv* env, const char* name, rc_t rc) {
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (rc == rc_t(-1)) {
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throwErrnoException(env, name);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return rc;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jobject makeStructStat(JNIEnv* env, const struct stat& sb) {
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    static jmethodID ctor = env->GetMethodID(JniConstants::structStatClass, "<init>",
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            "(JJIJIIJJJJJJJ)V");
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return env->NewObject(JniConstants::structStatClass, ctor,
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            jlong(sb.st_dev), jlong(sb.st_ino), jint(sb.st_mode), jlong(sb.st_nlink),
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            jint(sb.st_uid), jint(sb.st_gid), jlong(sb.st_rdev), jlong(sb.st_size),
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            jlong(sb.st_atime), jlong(sb.st_mtime), jlong(sb.st_ctime),
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry            jlong(sb.st_blksize), jlong(sb.st_blocks));
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jobject doStat(JNIEnv* env, jstring javaPath, bool isLstat) {
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    ScopedUtfChars path(env, javaPath);
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (path.c_str() == NULL) {
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return NULL;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    struct stat sb;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int rc = isLstat ? TEMP_FAILURE_RETRY(lstat(path.c_str(), &sb))
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                     : TEMP_FAILURE_RETRY(stat(path.c_str(), &sb));
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (rc == -1) {
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throwErrnoException(env, isLstat ? "lstat" : "stat");
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return NULL;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return makeStructStat(env, sb);
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jboolean Posix_access(JNIEnv* env, jobject, jstring javaPath, jint mode) {
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    ScopedUtfChars path(env, javaPath);
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (path.c_str() == NULL) {
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return JNI_FALSE;
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int rc = TEMP_FAILURE_RETRY(access(path.c_str(), mode));
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (rc == -1) {
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throwErrnoException(env, "access");
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return (rc == 0);
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jobjectArray Posix_environ(JNIEnv* env, jobject) {
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    extern char** environ; // Standard, but not in any header file.
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return toStringArray(env, environ);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_fdatasync(JNIEnv* env, jobject, jobject javaFd) {
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int fd = jniGetFDFromFileDescriptor(env, javaFd);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "fdatasync", TEMP_FAILURE_RETRY(fdatasync(fd)));
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jobject Posix_fstat(JNIEnv* env, jobject, jobject javaFd) {
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int fd = jniGetFDFromFileDescriptor(env, javaFd);
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    struct stat sb;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int rc = TEMP_FAILURE_RETRY(fstat(fd, &sb));
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (rc == -1) {
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throwErrnoException(env, "fstat");
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return NULL;
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return makeStructStat(env, sb);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_fsync(JNIEnv* env, jobject, jobject javaFd) {
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int fd = jniGetFDFromFileDescriptor(env, javaFd);
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "fsync", TEMP_FAILURE_RETRY(fsync(fd)));
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_ftruncate(JNIEnv* env, jobject, jobject javaFd, jlong length) {
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int fd = jniGetFDFromFileDescriptor(env, javaFd);
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "ftruncate", TEMP_FAILURE_RETRY(ftruncate64(fd, length)));
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jstring Posix_getenv(JNIEnv* env, jobject, jstring javaName) {
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    ScopedUtfChars name(env, javaName);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (name.c_str() == NULL) {
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return NULL;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return env->NewStringUTF(getenv(name.c_str()));
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jboolean Posix_isatty(JNIEnv* env, jobject, jobject javaFd) {
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int fd = jniGetFDFromFileDescriptor(env, javaFd);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return TEMP_FAILURE_RETRY(isatty(fd)) == 0;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jlong Posix_lseek(JNIEnv* env, jobject, jobject javaFd, jlong offset, jint whence) {
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int fd = jniGetFDFromFileDescriptor(env, javaFd);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return throwIfMinusOne(env, "lseek", TEMP_FAILURE_RETRY(lseek64(fd, offset, whence)));
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jobject Posix_lstat(JNIEnv* env, jobject, jstring javaPath) {
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return doStat(env, javaPath, true);
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) {
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    ScopedByteArrayRW vector(env, javaVector);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (vector.get() == NULL) {
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        return;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    unsigned char* vec = reinterpret_cast<unsigned char*>(vector.get());
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "mincore", TEMP_FAILURE_RETRY(mincore(ptr, byteCount, vec)));
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "mlock", TEMP_FAILURE_RETRY(mlock(ptr, byteCount)));
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jlong Posix_mmap(JNIEnv* env, jobject, jlong address, jlong byteCount, jint prot, jint flags, jobject javaFd, jlong offset) {
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int fd = jniGetFDFromFileDescriptor(env, javaFd);
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    void* suggestedPtr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    void* ptr = mmap(suggestedPtr, byteCount, prot, flags, fd, offset);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (ptr == MAP_FAILED) {
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throwErrnoException(env, "mmap");
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_msync(JNIEnv* env, jobject, jlong address, jlong byteCount, jint flags) {
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "msync", TEMP_FAILURE_RETRY(msync(ptr, byteCount, flags)));
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_munlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "munlock", TEMP_FAILURE_RETRY(munlock(ptr, byteCount)));
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void Posix_munmap(JNIEnv* env, jobject, jlong address, jlong byteCount) {
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    throwIfMinusOne(env, "munmap", TEMP_FAILURE_RETRY(munmap(ptr, byteCount)));
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jobject Posix_stat(JNIEnv* env, jobject, jstring javaPath) {
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return doStat(env, javaPath, false);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jstring Posix_strerror(JNIEnv* env, jobject, jint errnum) {
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    char buffer[BUFSIZ];
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const char* message = jniStrError(errnum, buffer, sizeof(buffer));
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return env->NewStringUTF(message);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic jlong Posix_sysconf(JNIEnv* env, jobject, jint name) {
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    // Since -1 is a valid result from sysconf(3), detecting failure is a little more awkward.
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    errno = 0;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    long result = sysconf(name);
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    if (result == -1L && errno == EINVAL) {
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        throwErrnoException(env, "sysconf");
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    }
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return result;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic JNINativeMethod gMethods[] = {
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"),
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, environ, "()[Ljava/lang/String;"),
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, fdatasync, "(Ljava/io/FileDescriptor;)V"),
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, fstat, "(Ljava/io/FileDescriptor;)Llibcore/io/StructStat;"),
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, fsync, "(Ljava/io/FileDescriptor;)V"),
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, getenv, "(Ljava/lang/String;)Ljava/lang/String;"),
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, isatty, "(Ljava/io/FileDescriptor;)Z"),
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, lseek, "(Ljava/io/FileDescriptor;JI)J"),
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, lstat, "(Ljava/lang/String;)Llibcore/io/StructStat;"),
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, mincore, "(JJ[B)V"),
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, mlock, "(JJ)V"),
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, mmap, "(JJIILjava/io/FileDescriptor;J)J"),
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, msync, "(JJI)V"),
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, munlock, "(JJ)V"),
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, munmap, "(JJ)V"),
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, stat, "(Ljava/lang/String;)Llibcore/io/StructStat;"),
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, strerror, "(I)Ljava/lang/String;"),
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NATIVE_METHOD(Posix, sysconf, "(I)J"),
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint register_libcore_io_Posix(JNIEnv* env) {
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return jniRegisterNativeMethods(env, "libcore/io/Posix", gMethods, NELEM(gMethods));
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry