Home | History | Annotate | Download | only in native
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "Linux"
     18 
     19 #include <arpa/inet.h>
     20 #include <errno.h>
     21 #include <fcntl.h>
     22 #include <ifaddrs.h>
     23 #include <linux/rtnetlink.h>
     24 #include <net/if.h>
     25 #include <netdb.h>
     26 #include <netinet/in.h>
     27 #include <netpacket/packet.h>
     28 #include <poll.h>
     29 #include <pwd.h>
     30 #include <signal.h>
     31 #include <stdlib.h>
     32 #include <sys/capability.h>
     33 #include <sys/ioctl.h>
     34 #include <sys/mman.h>
     35 #include <sys/prctl.h>
     36 #include <sys/resource.h>
     37 #include <sys/socket.h>
     38 #include <sys/stat.h>
     39 #include <sys/syscall.h>
     40 #include <sys/time.h>
     41 #include <sys/types.h>
     42 #include <sys/uio.h>
     43 #include <sys/un.h>
     44 #include <sys/utsname.h>
     45 #include <sys/wait.h>
     46 #include <sys/xattr.h>
     47 #include <termios.h>
     48 #include <unistd.h>
     49 
     50 #include <memory>
     51 
     52 #include <android-base/file.h>
     53 #include <android-base/logging.h>
     54 #include <android-base/strings.h>
     55 #include <log/log.h>
     56 #include <nativehelper/AsynchronousCloseMonitor.h>
     57 #include <nativehelper/JNIHelp.h>
     58 #include <nativehelper/JniConstants.h>
     59 #include <nativehelper/ScopedBytes.h>
     60 #include <nativehelper/ScopedLocalRef.h>
     61 #include <nativehelper/ScopedPrimitiveArray.h>
     62 #include <nativehelper/ScopedUtfChars.h>
     63 #include <nativehelper/toStringArray.h>
     64 
     65 #include "ExecStrings.h"
     66 #include "JniException.h"
     67 #include "NetworkUtilities.h"
     68 #include "Portability.h"
     69 
     70 #ifndef __unused
     71 #define __unused __attribute__((__unused__))
     72 #endif
     73 
     74 #define TO_JAVA_STRING(NAME, EXP) \
     75         jstring NAME = env->NewStringUTF(EXP); \
     76         if ((NAME) == NULL) return NULL;
     77 
     78 namespace {
     79 
     80 jfieldID int32RefValueFid;
     81 jfieldID int64RefValueFid;
     82 
     83 }  // namespace
     84 
     85 struct addrinfo_deleter {
     86     void operator()(addrinfo* p) const {
     87         if (p != NULL) { // bionic's freeaddrinfo(3) crashes when passed NULL.
     88             freeaddrinfo(p);
     89         }
     90     }
     91 };
     92 
     93 struct c_deleter {
     94     void operator()(void* p) const {
     95         free(p);
     96     }
     97 };
     98 
     99 static bool isIPv4MappedAddress(const sockaddr *sa) {
    100     const sockaddr_in6 *sin6 = reinterpret_cast<const sockaddr_in6*>(sa);
    101     return sa != NULL && sa->sa_family == AF_INET6 &&
    102            (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ||
    103             IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr));  // We map 0.0.0.0 to ::, so :: is mapped.
    104 }
    105 
    106 /**
    107  * Perform a socket operation that specifies an IP address, possibly falling back from specifying
    108  * the address as an IPv4-mapped IPv6 address in a struct sockaddr_in6 to specifying it as an IPv4
    109  * address in a struct sockaddr_in.
    110  *
    111  * This is needed because all sockets created by the java.net APIs are IPv6 sockets, and on those
    112  * sockets, IPv4 operations use IPv4-mapped addresses stored in a struct sockaddr_in6. But sockets
    113  * created using Linux.socket(AF_INET, ...) are IPv4 sockets and only support operations using IPv4
    114  * socket addresses structures.
    115  */
    116 #define NET_IPV4_FALLBACK(jni_env, return_type, syscall_name, java_fd, java_addr, port, null_addr_ok, args...) ({ \
    117     return_type _rc = -1; \
    118     do { \
    119         sockaddr_storage _ss; \
    120         socklen_t _salen; \
    121         if ((java_addr) == NULL && (null_addr_ok)) { \
    122             /* No IP address specified (e.g., sendto() on a connected socket). */ \
    123             _salen = 0; \
    124         } else if (!inetAddressToSockaddr(jni_env, java_addr, port, _ss, _salen)) { \
    125             /* Invalid socket address, return -1. inetAddressToSockaddr has already thrown. */ \
    126             break; \
    127         } \
    128         sockaddr* _sa = _salen ? reinterpret_cast<sockaddr*>(&_ss) : NULL; \
    129         /* inetAddressToSockaddr always returns an IPv6 sockaddr. Assume that java_fd was created \
    130          * by Java API calls, which always create IPv6 socket fds, and pass it in as is. */ \
    131         _rc = NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ##args, _sa, _salen); \
    132         if (_rc == -1 && errno == EAFNOSUPPORT && _salen && isIPv4MappedAddress(_sa)) { \
    133             /* We passed in an IPv4 address in an IPv6 sockaddr and the kernel told us that we got \
    134              * the address family wrong. Pass in the same address in an IPv4 sockaddr. */ \
    135             (jni_env)->ExceptionClear(); \
    136             if (!inetAddressToSockaddrVerbatim(jni_env, java_addr, port, _ss, _salen)) { \
    137                 break; \
    138             } \
    139             _sa = reinterpret_cast<sockaddr*>(&_ss); \
    140             _rc = NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ##args, _sa, _salen); \
    141         } \
    142     } while (0); \
    143     _rc; }) \
    144 
    145 /**
    146  * Used to retry networking system calls that can be interrupted with a signal. Unlike
    147  * TEMP_FAILURE_RETRY, this also handles the case where
    148  * AsynchronousCloseMonitor::signalBlockedThreads(fd) is used to signal a close() or
    149  * Thread.interrupt(). Other signals that result in an EINTR result are ignored and the system call
    150  * is retried.
    151  *
    152  * Returns the result of the system call though a Java exception will be pending if the result is
    153  * -1:  a SocketException if signaled via AsynchronousCloseMonitor, or ErrnoException for other
    154  * failures.
    155  */
    156 #define NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ...) ({ \
    157     return_type _rc = -1; \
    158     int _syscallErrno; \
    159     do { \
    160         bool _wasSignaled; \
    161         { \
    162             int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
    163             AsynchronousCloseMonitor _monitor(_fd); \
    164             _rc = syscall_name(_fd, __VA_ARGS__); \
    165             _syscallErrno = errno; \
    166             _wasSignaled = _monitor.wasSignaled(); \
    167         } \
    168         if (_wasSignaled) { \
    169             jniThrowException(jni_env, "java/net/SocketException", "Socket closed"); \
    170             _rc = -1; \
    171             break; \
    172         } \
    173         if (_rc == -1 && _syscallErrno != EINTR) { \
    174             /* TODO: with a format string we could show the arguments too, like strace(1). */ \
    175             throwErrnoException(jni_env, # syscall_name); \
    176             break; \
    177         } \
    178     } while (_rc == -1); /* _syscallErrno == EINTR && !_wasSignaled */ \
    179     if (_rc == -1) { \
    180         /* If the syscall failed, re-set errno: throwing an exception might have modified it. */ \
    181         errno = _syscallErrno; \
    182     } \
    183     _rc; })
    184 
    185 /**
    186  * Used to retry system calls that can be interrupted with a signal. Unlike TEMP_FAILURE_RETRY, this
    187  * also handles the case where AsynchronousCloseMonitor::signalBlockedThreads(fd) is used to signal
    188  * a close() or Thread.interrupt(). Other signals that result in an EINTR result are ignored and the
    189  * system call is retried.
    190  *
    191  * Returns the result of the system call though a Java exception will be pending if the result is
    192  * -1: an IOException if the file descriptor is already closed, a InterruptedIOException if signaled
    193  * via AsynchronousCloseMonitor, or ErrnoException for other failures.
    194  */
    195 #define IO_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ...) ({ \
    196     return_type _rc = -1; \
    197     int _syscallErrno; \
    198     do { \
    199         bool _wasSignaled; \
    200         { \
    201             int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
    202             AsynchronousCloseMonitor _monitor(_fd); \
    203             _rc = syscall_name(_fd, __VA_ARGS__); \
    204             _syscallErrno = errno; \
    205             _wasSignaled = _monitor.wasSignaled(); \
    206         } \
    207         if (_wasSignaled) { \
    208             jniThrowException(jni_env, "java/io/InterruptedIOException", # syscall_name " interrupted"); \
    209             _rc = -1; \
    210             break; \
    211         } \
    212         if (_rc == -1 && _syscallErrno != EINTR) { \
    213             /* TODO: with a format string we could show the arguments too, like strace(1). */ \
    214             throwErrnoException(jni_env, # syscall_name); \
    215             break; \
    216         } \
    217     } while (_rc == -1); /* && _syscallErrno == EINTR && !_wasSignaled */ \
    218     if (_rc == -1) { \
    219         /* If the syscall failed, re-set errno: throwing an exception might have modified it. */ \
    220         errno = _syscallErrno; \
    221     } \
    222     _rc; })
    223 
    224 #define NULL_ADDR_OK         true
    225 #define NULL_ADDR_FORBIDDEN  false
    226 
    227 static void throwException(JNIEnv* env, jclass exceptionClass, jmethodID ctor3, jmethodID ctor2,
    228         const char* functionName, int error) {
    229     jthrowable cause = NULL;
    230     if (env->ExceptionCheck()) {
    231         cause = env->ExceptionOccurred();
    232         env->ExceptionClear();
    233     }
    234 
    235     ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName));
    236     if (detailMessage.get() == NULL) {
    237         // Not really much we can do here. We're probably dead in the water,
    238         // but let's try to stumble on...
    239         env->ExceptionClear();
    240     }
    241 
    242     jobject exception;
    243     if (cause != NULL) {
    244         exception = env->NewObject(exceptionClass, ctor3, detailMessage.get(), error, cause);
    245     } else {
    246         exception = env->NewObject(exceptionClass, ctor2, detailMessage.get(), error);
    247     }
    248     env->Throw(reinterpret_cast<jthrowable>(exception));
    249 }
    250 
    251 static void throwErrnoException(JNIEnv* env, const char* functionName) {
    252     int error = errno;
    253     static jmethodID ctor3 = env->GetMethodID(JniConstants::errnoExceptionClass,
    254             "<init>", "(Ljava/lang/String;ILjava/lang/Throwable;)V");
    255     static jmethodID ctor2 = env->GetMethodID(JniConstants::errnoExceptionClass,
    256             "<init>", "(Ljava/lang/String;I)V");
    257     throwException(env, JniConstants::errnoExceptionClass, ctor3, ctor2, functionName, error);
    258 }
    259 
    260 static void throwGaiException(JNIEnv* env, const char* functionName, int error) {
    261   // Cache the methods ids before we throw, so we don't call GetMethodID with a pending exception.
    262   static jmethodID ctor3 = env->GetMethodID(JniConstants::gaiExceptionClass, "<init>",
    263                                             "(Ljava/lang/String;ILjava/lang/Throwable;)V");
    264   static jmethodID ctor2 = env->GetMethodID(JniConstants::gaiExceptionClass, "<init>",
    265                                             "(Ljava/lang/String;I)V");
    266   if (errno != 0) {
    267         // EAI_SYSTEM should mean "look at errno instead", but both glibc and bionic seem to
    268         // mess this up. In particular, if you don't have INTERNET permission, errno will be EACCES
    269         // but you'll get EAI_NONAME or EAI_NODATA. So we want our GaiException to have a
    270         // potentially-relevant ErrnoException as its cause even if error != EAI_SYSTEM.
    271         // http://code.google.com/p/android/issues/detail?id=15722
    272         throwErrnoException(env, functionName);
    273         // Deliberately fall through to throw another exception...
    274     }
    275     throwException(env, JniConstants::gaiExceptionClass, ctor3, ctor2, functionName, error);
    276 }
    277 
    278 template <typename rc_t>
    279 static rc_t throwIfMinusOne(JNIEnv* env, const char* name, rc_t rc) {
    280     if (rc == rc_t(-1)) {
    281         throwErrnoException(env, name);
    282     }
    283     return rc;
    284 }
    285 
    286 template <typename ScopedT>
    287 class IoVec {
    288 public:
    289     IoVec(JNIEnv* env, size_t bufferCount) : mEnv(env), mBufferCount(bufferCount) {
    290     }
    291 
    292     bool init(jobjectArray javaBuffers, jintArray javaOffsets, jintArray javaByteCounts) {
    293         // We can't delete our local references until after the I/O, so make sure we have room.
    294         if (mEnv->PushLocalFrame(mBufferCount + 16) < 0) {
    295             return false;
    296         }
    297         ScopedIntArrayRO offsets(mEnv, javaOffsets);
    298         if (offsets.get() == NULL) {
    299             return false;
    300         }
    301         ScopedIntArrayRO byteCounts(mEnv, javaByteCounts);
    302         if (byteCounts.get() == NULL) {
    303             return false;
    304         }
    305         // TODO: Linux actually has a 1024 buffer limit. glibc works around this, and we should too.
    306         // TODO: you can query the limit at runtime with sysconf(_SC_IOV_MAX).
    307         for (size_t i = 0; i < mBufferCount; ++i) {
    308             jobject buffer = mEnv->GetObjectArrayElement(javaBuffers, i); // We keep this local ref.
    309             mScopedBuffers.push_back(new ScopedT(mEnv, buffer));
    310             jbyte* ptr = const_cast<jbyte*>(mScopedBuffers.back()->get());
    311             if (ptr == NULL) {
    312                 return false;
    313             }
    314             struct iovec iov;
    315             iov.iov_base = reinterpret_cast<void*>(ptr + offsets[i]);
    316             iov.iov_len = byteCounts[i];
    317             mIoVec.push_back(iov);
    318         }
    319         return true;
    320     }
    321 
    322     ~IoVec() {
    323         for (size_t i = 0; i < mScopedBuffers.size(); ++i) {
    324             delete mScopedBuffers[i];
    325         }
    326         mEnv->PopLocalFrame(NULL);
    327     }
    328 
    329     iovec* get() {
    330         return &mIoVec[0];
    331     }
    332 
    333     size_t size() {
    334         return mBufferCount;
    335     }
    336 
    337 private:
    338     JNIEnv* mEnv;
    339     size_t mBufferCount;
    340     std::vector<iovec> mIoVec;
    341     std::vector<ScopedT*> mScopedBuffers;
    342 };
    343 
    344 /**
    345  * Returns a jbyteArray containing the sockaddr_un.sun_path from ss. As per unix(7) sa_len should be
    346  * the length of ss as returned by getsockname(2), getpeername(2), or accept(2).
    347  * If the returned array is of length 0 the sockaddr_un refers to an unnamed socket.
    348  * A null pointer is returned in the event of an error. See unix(7) for more information.
    349  */
    350 static jbyteArray getUnixSocketPath(JNIEnv* env, const sockaddr_storage& ss,
    351         const socklen_t& sa_len) {
    352     if (ss.ss_family != AF_UNIX) {
    353         jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
    354                 "getUnixSocketPath unsupported ss_family: %i", ss.ss_family);
    355         return NULL;
    356     }
    357 
    358     const struct sockaddr_un* un_addr = reinterpret_cast<const struct sockaddr_un*>(&ss);
    359     // The length of sun_path is sa_len minus the length of the overhead (ss_family).
    360     // See unix(7) for details. This calculation must match that of socket_make_sockaddr_un() in
    361     // socket_local_client.c and javaUnixSocketAddressToSockaddr() to interoperate.
    362     size_t pathLength = sa_len - offsetof(struct sockaddr_un, sun_path);
    363 
    364     jbyteArray javaSunPath = env->NewByteArray(pathLength);
    365     if (javaSunPath == NULL) {
    366         return NULL;
    367     }
    368 
    369     if (pathLength > 0) {
    370         env->SetByteArrayRegion(javaSunPath, 0, pathLength,
    371                 reinterpret_cast<const jbyte*>(&un_addr->sun_path));
    372     }
    373     return javaSunPath;
    374 }
    375 
    376 static jobject makeSocketAddress(JNIEnv* env, const sockaddr_storage& ss, const socklen_t sa_len) {
    377     if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
    378         jint port;
    379         jobject inetAddress = sockaddrToInetAddress(env, ss, &port);
    380         if (inetAddress == NULL) {
    381             return NULL;  // Exception already thrown.
    382         }
    383         static jmethodID ctor = env->GetMethodID(JniConstants::inetSocketAddressClass,
    384                 "<init>", "(Ljava/net/InetAddress;I)V");
    385         if (ctor == NULL) {
    386             return NULL;
    387         }
    388         return env->NewObject(JniConstants::inetSocketAddressClass, ctor, inetAddress, port);
    389     } else if (ss.ss_family == AF_UNIX) {
    390         static jmethodID ctor = env->GetMethodID(JniConstants::unixSocketAddressClass,
    391                 "<init>", "([B)V");
    392         if (ctor == NULL) {
    393             return NULL;
    394         }
    395         jbyteArray javaSunPath = getUnixSocketPath(env, ss, sa_len);
    396         if (!javaSunPath) {
    397             return NULL;
    398         }
    399         return env->NewObject(JniConstants::unixSocketAddressClass, ctor, javaSunPath);
    400     } else if (ss.ss_family == AF_NETLINK) {
    401         const struct sockaddr_nl* nl_addr = reinterpret_cast<const struct sockaddr_nl*>(&ss);
    402         static jmethodID ctor = env->GetMethodID(JniConstants::netlinkSocketAddressClass,
    403                 "<init>", "(II)V");
    404         if (ctor == NULL) {
    405             return NULL;
    406         }
    407         return env->NewObject(JniConstants::netlinkSocketAddressClass, ctor,
    408                 static_cast<jint>(nl_addr->nl_pid),
    409                 static_cast<jint>(nl_addr->nl_groups));
    410     } else if (ss.ss_family == AF_PACKET) {
    411         const struct sockaddr_ll* sll = reinterpret_cast<const struct sockaddr_ll*>(&ss);
    412         static jmethodID ctor = env->GetMethodID(JniConstants::packetSocketAddressClass,
    413                 "<init>", "(SISB[B)V");
    414         if (ctor == NULL) {
    415             return NULL;
    416         }
    417         ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(sll->sll_halen));
    418         if (byteArray.get() == NULL) {
    419             return NULL;
    420         }
    421         env->SetByteArrayRegion(byteArray.get(), 0, sll->sll_halen,
    422                 reinterpret_cast<const jbyte*>(sll->sll_addr));
    423         jobject packetSocketAddress = env->NewObject(JniConstants::packetSocketAddressClass, ctor,
    424                 static_cast<jshort>(ntohs(sll->sll_protocol)),
    425                 static_cast<jint>(sll->sll_ifindex),
    426                 static_cast<jshort>(sll->sll_hatype),
    427                 static_cast<jbyte>(sll->sll_pkttype),
    428                 byteArray.get());
    429         return packetSocketAddress;
    430     }
    431     jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "unsupported ss_family: %d",
    432             ss.ss_family);
    433     return NULL;
    434 }
    435 
    436 static jobject makeStructPasswd(JNIEnv* env, const struct passwd& pw) {
    437     TO_JAVA_STRING(pw_name, pw.pw_name);
    438     TO_JAVA_STRING(pw_dir, pw.pw_dir);
    439     TO_JAVA_STRING(pw_shell, pw.pw_shell);
    440     static jmethodID ctor = env->GetMethodID(JniConstants::structPasswdClass, "<init>",
    441             "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
    442     if (ctor == NULL) {
    443         return NULL;
    444     }
    445     return env->NewObject(JniConstants::structPasswdClass, ctor,
    446             pw_name, static_cast<jint>(pw.pw_uid), static_cast<jint>(pw.pw_gid), pw_dir, pw_shell);
    447 }
    448 
    449 static jobject makeStructTimespec(JNIEnv* env, const struct timespec& ts) {
    450     static jmethodID ctor = env->GetMethodID(JniConstants::structTimespecClass, "<init>",
    451             "(JJ)V");
    452     if (ctor == NULL) {
    453         return NULL;
    454     }
    455     return env->NewObject(JniConstants::structTimespecClass, ctor,
    456             static_cast<jlong>(ts.tv_sec), static_cast<jlong>(ts.tv_nsec));
    457 }
    458 
    459 static jobject makeStructStat(JNIEnv* env, const struct stat64& sb) {
    460     static jmethodID ctor = env->GetMethodID(JniConstants::structStatClass, "<init>",
    461             "(JJIJIIJJLandroid/system/StructTimespec;Landroid/system/StructTimespec;Landroid/system/StructTimespec;JJ)V");
    462     if (ctor == NULL) {
    463         return NULL;
    464     }
    465 
    466     jobject atim_timespec = makeStructTimespec(env, sb.st_atim);
    467     if (atim_timespec == NULL) {
    468         return NULL;
    469     }
    470     jobject mtim_timespec = makeStructTimespec(env, sb.st_mtim);
    471     if (mtim_timespec == NULL) {
    472         return NULL;
    473     }
    474     jobject ctim_timespec = makeStructTimespec(env, sb.st_ctim);
    475     if (ctim_timespec == NULL) {
    476         return NULL;
    477     }
    478 
    479     return env->NewObject(JniConstants::structStatClass, ctor,
    480             static_cast<jlong>(sb.st_dev), static_cast<jlong>(sb.st_ino),
    481             static_cast<jint>(sb.st_mode), static_cast<jlong>(sb.st_nlink),
    482             static_cast<jint>(sb.st_uid), static_cast<jint>(sb.st_gid),
    483             static_cast<jlong>(sb.st_rdev), static_cast<jlong>(sb.st_size),
    484             atim_timespec, mtim_timespec, ctim_timespec,
    485             static_cast<jlong>(sb.st_blksize), static_cast<jlong>(sb.st_blocks));
    486 }
    487 
    488 static jobject makeStructStatVfs(JNIEnv* env, const struct statvfs& sb) {
    489     static jmethodID ctor = env->GetMethodID(JniConstants::structStatVfsClass, "<init>",
    490             "(JJJJJJJJJJJ)V");
    491     if (ctor == NULL) {
    492         return NULL;
    493     }
    494 
    495     return env->NewObject(JniConstants::structStatVfsClass, ctor,
    496                           static_cast<jlong>(sb.f_bsize),
    497                           static_cast<jlong>(sb.f_frsize),
    498                           static_cast<jlong>(sb.f_blocks),
    499                           static_cast<jlong>(sb.f_bfree),
    500                           static_cast<jlong>(sb.f_bavail),
    501                           static_cast<jlong>(sb.f_files),
    502                           static_cast<jlong>(sb.f_ffree),
    503                           static_cast<jlong>(sb.f_favail),
    504                           static_cast<jlong>(sb.f_fsid),
    505                           static_cast<jlong>(sb.f_flag),
    506                           static_cast<jlong>(sb.f_namemax));
    507 }
    508 
    509 static jobject makeStructLinger(JNIEnv* env, const struct linger& l) {
    510     static jmethodID ctor = env->GetMethodID(JniConstants::structLingerClass, "<init>", "(II)V");
    511     if (ctor == NULL) {
    512         return NULL;
    513     }
    514     return env->NewObject(JniConstants::structLingerClass, ctor, l.l_onoff, l.l_linger);
    515 }
    516 
    517 static jobject makeStructTimeval(JNIEnv* env, const struct timeval& tv) {
    518     static jmethodID ctor = env->GetMethodID(JniConstants::structTimevalClass, "<init>", "(JJ)V");
    519     if (ctor == NULL) {
    520         return NULL;
    521     }
    522     return env->NewObject(JniConstants::structTimevalClass, ctor,
    523             static_cast<jlong>(tv.tv_sec), static_cast<jlong>(tv.tv_usec));
    524 }
    525 
    526 static jobject makeStructUcred(JNIEnv* env, const struct ucred& u __unused) {
    527     static jmethodID ctor = env->GetMethodID(JniConstants::structUcredClass, "<init>", "(III)V");
    528     if (ctor == NULL) {
    529         return NULL;
    530     }
    531     return env->NewObject(JniConstants::structUcredClass, ctor, u.pid, u.uid, u.gid);
    532 }
    533 
    534 static jobject makeStructUtsname(JNIEnv* env, const struct utsname& buf) {
    535     TO_JAVA_STRING(sysname, buf.sysname);
    536     TO_JAVA_STRING(nodename, buf.nodename);
    537     TO_JAVA_STRING(release, buf.release);
    538     TO_JAVA_STRING(version, buf.version);
    539     TO_JAVA_STRING(machine, buf.machine);
    540     static jmethodID ctor = env->GetMethodID(JniConstants::structUtsnameClass, "<init>",
    541             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
    542     if (ctor == NULL) {
    543         return NULL;
    544     }
    545     return env->NewObject(JniConstants::structUtsnameClass, ctor,
    546             sysname, nodename, release, version, machine);
    547 };
    548 
    549 static bool fillIfreq(JNIEnv* env, jstring javaInterfaceName, struct ifreq& req) {
    550     ScopedUtfChars interfaceName(env, javaInterfaceName);
    551     if (interfaceName.c_str() == NULL) {
    552         return false;
    553     }
    554     memset(&req, 0, sizeof(req));
    555     strncpy(req.ifr_name, interfaceName.c_str(), sizeof(req.ifr_name));
    556     req.ifr_name[sizeof(req.ifr_name) - 1] = '\0';
    557     return true;
    558 }
    559 
    560 static bool fillUnixSocketAddress(JNIEnv* env, jobject javaUnixSocketAddress,
    561         const sockaddr_storage& ss, const socklen_t& sa_len) {
    562     if (javaUnixSocketAddress == NULL) {
    563         return true;
    564     }
    565     jbyteArray javaSunPath = getUnixSocketPath(env, ss, sa_len);
    566     if (!javaSunPath) {
    567         return false;
    568     }
    569 
    570     static jfieldID sunPathFid =
    571             env->GetFieldID(JniConstants::unixSocketAddressClass, "sun_path", "[B");
    572     env->SetObjectField(javaUnixSocketAddress, sunPathFid, javaSunPath);
    573     return true;
    574 }
    575 
    576 static bool fillInetSocketAddress(JNIEnv* env, jobject javaInetSocketAddress,
    577         const sockaddr_storage& ss) {
    578     if (javaInetSocketAddress == NULL) {
    579         return true;
    580     }
    581     // Fill out the passed-in InetSocketAddress with the sender's IP address and port number.
    582     jint port;
    583     jobject sender = sockaddrToInetAddress(env, ss, &port);
    584     if (sender == NULL) {
    585         return false;
    586     }
    587     static jfieldID holderFid = env->GetFieldID(JniConstants::inetSocketAddressClass, "holder",
    588                                                 "Ljava/net/InetSocketAddress$InetSocketAddressHolder;");
    589     jobject holder = env->GetObjectField(javaInetSocketAddress, holderFid);
    590 
    591     static jfieldID addressFid = env->GetFieldID(JniConstants::inetSocketAddressHolderClass,
    592                                                  "addr", "Ljava/net/InetAddress;");
    593     static jfieldID portFid = env->GetFieldID(JniConstants::inetSocketAddressHolderClass, "port", "I");
    594     env->SetObjectField(holder, addressFid, sender);
    595     env->SetIntField(holder, portFid, port);
    596     return true;
    597 }
    598 
    599 static bool fillSocketAddress(JNIEnv* env, jobject javaSocketAddress, const sockaddr_storage& ss,
    600         const socklen_t& sa_len) {
    601     if (javaSocketAddress == NULL) {
    602         return true;
    603     }
    604 
    605     if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
    606         return fillInetSocketAddress(env, javaSocketAddress, ss);
    607     } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::unixSocketAddressClass)) {
    608         return fillUnixSocketAddress(env, javaSocketAddress, ss, sa_len);
    609     }
    610     jniThrowException(env, "java/lang/UnsupportedOperationException",
    611             "unsupported SocketAddress subclass");
    612     return false;
    613 
    614 }
    615 
    616 static void javaInetSocketAddressToInetAddressAndPort(
    617         JNIEnv* env, jobject javaInetSocketAddress, jobject& javaInetAddress, jint& port) {
    618     static jfieldID holderFid = env->GetFieldID(JniConstants::inetSocketAddressClass, "holder",
    619                                                 "Ljava/net/InetSocketAddress$InetSocketAddressHolder;");
    620     jobject holder = env->GetObjectField(javaInetSocketAddress, holderFid);
    621 
    622     static jfieldID addressFid = env->GetFieldID(
    623             JniConstants::inetSocketAddressHolderClass, "addr", "Ljava/net/InetAddress;");
    624     static jfieldID portFid = env->GetFieldID(JniConstants::inetSocketAddressHolderClass, "port", "I");
    625 
    626     javaInetAddress = env->GetObjectField(holder, addressFid);
    627     port = env->GetIntField(holder, portFid);
    628 }
    629 
    630 static bool javaInetSocketAddressToSockaddr(
    631         JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
    632     jobject javaInetAddress;
    633     jint port;
    634     javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port);
    635     return inetAddressToSockaddr(env, javaInetAddress, port, ss, sa_len);
    636 }
    637 
    638 static bool javaNetlinkSocketAddressToSockaddr(
    639         JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
    640     static jfieldID nlPidFid = env->GetFieldID(
    641             JniConstants::netlinkSocketAddressClass, "nlPortId", "I");
    642     static jfieldID nlGroupsFid = env->GetFieldID(
    643             JniConstants::netlinkSocketAddressClass, "nlGroupsMask", "I");
    644 
    645     sockaddr_nl *nlAddr = reinterpret_cast<sockaddr_nl *>(&ss);
    646     nlAddr->nl_family = AF_NETLINK;
    647     nlAddr->nl_pid = env->GetIntField(javaSocketAddress, nlPidFid);
    648     nlAddr->nl_groups = env->GetIntField(javaSocketAddress, nlGroupsFid);
    649     sa_len = sizeof(sockaddr_nl);
    650     return true;
    651 }
    652 
    653 static bool javaUnixSocketAddressToSockaddr(
    654         JNIEnv* env, jobject javaUnixSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
    655     static jfieldID sunPathFid = env->GetFieldID(
    656             JniConstants::unixSocketAddressClass, "sun_path", "[B");
    657 
    658     struct sockaddr_un* un_addr = reinterpret_cast<struct sockaddr_un*>(&ss);
    659     memset (un_addr, 0, sizeof(sockaddr_un));
    660     un_addr->sun_family = AF_UNIX;
    661 
    662     jbyteArray javaSunPath = (jbyteArray) env->GetObjectField(javaUnixSocketAddress, sunPathFid);
    663     jsize pathLength = env->GetArrayLength(javaSunPath);
    664     if ((size_t) pathLength > sizeof(sockaddr_un::sun_path)) {
    665         jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
    666                 "sun_path too long: max=%i, is=%i",
    667                 sizeof(sockaddr_un::sun_path), pathLength);
    668         return false;
    669     }
    670     env->GetByteArrayRegion(javaSunPath, 0, pathLength, (jbyte*) un_addr->sun_path);
    671     // sa_len is sun_path plus the length of the overhead (ss_family_t). See unix(7) for
    672     // details. This calculation must match that of socket_make_sockaddr_un() in
    673     // socket_local_client.c and getUnixSocketPath() to interoperate.
    674     sa_len = offsetof(struct sockaddr_un, sun_path) + pathLength;
    675     return true;
    676 }
    677 
    678 static bool javaPacketSocketAddressToSockaddr(
    679         JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
    680     static jfieldID protocolFid = env->GetFieldID(
    681             JniConstants::packetSocketAddressClass, "sll_protocol", "S");
    682     static jfieldID ifindexFid = env->GetFieldID(
    683             JniConstants::packetSocketAddressClass, "sll_ifindex", "I");
    684     static jfieldID hatypeFid = env->GetFieldID(
    685             JniConstants::packetSocketAddressClass, "sll_hatype", "S");
    686     static jfieldID pkttypeFid = env->GetFieldID(
    687             JniConstants::packetSocketAddressClass, "sll_pkttype", "B");
    688     static jfieldID addrFid = env->GetFieldID(
    689             JniConstants::packetSocketAddressClass, "sll_addr", "[B");
    690 
    691     sockaddr_ll *sll = reinterpret_cast<sockaddr_ll *>(&ss);
    692     sll->sll_family = AF_PACKET;
    693     sll->sll_protocol = htons(env->GetShortField(javaSocketAddress, protocolFid));
    694     sll->sll_ifindex = env->GetIntField(javaSocketAddress, ifindexFid);
    695     sll->sll_hatype = env->GetShortField(javaSocketAddress, hatypeFid);
    696     sll->sll_pkttype = env->GetByteField(javaSocketAddress, pkttypeFid);
    697 
    698     jbyteArray sllAddr = (jbyteArray) env->GetObjectField(javaSocketAddress, addrFid);
    699     if (sllAddr == NULL) {
    700         sll->sll_halen = 0;
    701         memset(&sll->sll_addr, 0, sizeof(sll->sll_addr));
    702     } else {
    703         jsize len = env->GetArrayLength(sllAddr);
    704         if ((size_t) len > sizeof(sll->sll_addr)) {
    705             len = sizeof(sll->sll_addr);
    706         }
    707         sll->sll_halen = len;
    708         env->GetByteArrayRegion(sllAddr, 0, len, (jbyte*) sll->sll_addr);
    709     }
    710     sa_len = sizeof(sockaddr_ll);
    711     return true;
    712 }
    713 
    714 static bool javaSocketAddressToSockaddr(
    715         JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
    716     if (javaSocketAddress == NULL) {
    717         jniThrowNullPointerException(env, NULL);
    718         return false;
    719     }
    720 
    721     if (env->IsInstanceOf(javaSocketAddress, JniConstants::netlinkSocketAddressClass)) {
    722         return javaNetlinkSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
    723     } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
    724         return javaInetSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
    725     } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::packetSocketAddressClass)) {
    726         return javaPacketSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
    727     } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::unixSocketAddressClass)) {
    728         return javaUnixSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
    729     }
    730     jniThrowException(env, "java/lang/UnsupportedOperationException",
    731             "unsupported SocketAddress subclass");
    732     return false;
    733 }
    734 
    735 static jobject doStat(JNIEnv* env, jstring javaPath, bool isLstat) {
    736     ScopedUtfChars path(env, javaPath);
    737     if (path.c_str() == NULL) {
    738         return NULL;
    739     }
    740     struct stat64 sb;
    741     int rc = isLstat ? TEMP_FAILURE_RETRY(lstat64(path.c_str(), &sb))
    742                      : TEMP_FAILURE_RETRY(stat64(path.c_str(), &sb));
    743     if (rc == -1) {
    744         throwErrnoException(env, isLstat ? "lstat" : "stat");
    745         return NULL;
    746     }
    747     return makeStructStat(env, sb);
    748 }
    749 
    750 static jobject doGetSockName(JNIEnv* env, jobject javaFd, bool is_sockname) {
    751   int fd = jniGetFDFromFileDescriptor(env, javaFd);
    752   sockaddr_storage ss;
    753   sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
    754   socklen_t byteCount = sizeof(ss);
    755   memset(&ss, 0, byteCount);
    756   int rc = is_sockname ? TEMP_FAILURE_RETRY(getsockname(fd, sa, &byteCount))
    757       : TEMP_FAILURE_RETRY(getpeername(fd, sa, &byteCount));
    758   if (rc == -1) {
    759     throwErrnoException(env, is_sockname ? "getsockname" : "getpeername");
    760     return NULL;
    761   }
    762   return makeSocketAddress(env, ss, byteCount);
    763 }
    764 
    765 class Passwd {
    766 public:
    767     explicit Passwd(JNIEnv* env) : mEnv(env), mResult(NULL) {
    768         mBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX);
    769         mBuffer.reset(new char[mBufferSize]);
    770     }
    771 
    772     jobject getpwnam(const char* name) {
    773         return process("getpwnam_r", getpwnam_r(name, &mPwd, mBuffer.get(), mBufferSize, &mResult));
    774     }
    775 
    776     jobject getpwuid(uid_t uid) {
    777         return process("getpwuid_r", getpwuid_r(uid, &mPwd, mBuffer.get(), mBufferSize, &mResult));
    778     }
    779 
    780     struct passwd* get() {
    781         return mResult;
    782     }
    783 
    784 private:
    785     jobject process(const char* syscall, int error) {
    786         if (mResult == NULL) {
    787             errno = error;
    788             throwErrnoException(mEnv, syscall);
    789             return NULL;
    790         }
    791         return makeStructPasswd(mEnv, *mResult);
    792     }
    793 
    794     JNIEnv* mEnv;
    795     std::unique_ptr<char[]> mBuffer;
    796     size_t mBufferSize;
    797     struct passwd mPwd;
    798     struct passwd* mResult;
    799 };
    800 
    801 static void AssertException(JNIEnv* env) {
    802     if (env->ExceptionCheck() == JNI_FALSE) {
    803         env->FatalError("Expected exception");
    804     }
    805 }
    806 
    807 // Note for capabilities functions:
    808 // We assume the calls are rare enough that it does not make sense to cache class objects. The
    809 // advantage is lower maintenance burden.
    810 
    811 static bool ReadStructCapUserHeader(
    812         JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
    813     if (java_header == nullptr) {
    814         jniThrowNullPointerException(env, "header is null");
    815         return false;
    816     }
    817 
    818     ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
    819     if (header_class.get() == nullptr) {
    820         return false;
    821     }
    822 
    823     {
    824         static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
    825         if (version_fid == nullptr) {
    826             return false;
    827         }
    828         c_header->version = env->GetIntField(java_header, version_fid);
    829     }
    830 
    831     {
    832         static jfieldID pid_fid = env->GetFieldID(header_class.get(), "pid", "I");
    833         if (pid_fid == nullptr) {
    834             return false;
    835         }
    836         c_header->pid = env->GetIntField(java_header, pid_fid);
    837     }
    838 
    839     return true;
    840 }
    841 
    842 static void SetStructCapUserHeaderVersion(
    843         JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
    844     ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
    845     if (header_class.get() == nullptr) {
    846         env->ExceptionClear();
    847         return;
    848     }
    849 
    850     static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
    851     if (version_fid == nullptr) {
    852         env->ExceptionClear();
    853         return;
    854     }
    855     env->SetIntField(java_header, version_fid, c_header->version);
    856 }
    857 
    858 static jobject CreateStructCapUserData(
    859         JNIEnv* env, jclass data_class, __user_cap_data_struct* c_data) {
    860     if (c_data == nullptr) {
    861         // Should not happen.
    862         jniThrowNullPointerException(env, "data is null");
    863         return nullptr;
    864     }
    865 
    866     static jmethodID data_cons = env->GetMethodID(data_class, "<init>", "(III)V");
    867     if (data_cons == nullptr) {
    868         return nullptr;
    869     }
    870 
    871     jint e = static_cast<jint>(c_data->effective);
    872     jint p = static_cast<jint>(c_data->permitted);
    873     jint i = static_cast<jint>(c_data->inheritable);
    874     return env->NewObject(data_class, data_cons, e, p, i);
    875 }
    876 
    877 static bool ReadStructCapUserData(JNIEnv* env, jobject java_data, __user_cap_data_struct* c_data) {
    878     if (java_data == nullptr) {
    879         jniThrowNullPointerException(env, "data is null");
    880         return false;
    881     }
    882 
    883     ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
    884     if (data_class.get() == nullptr) {
    885         return false;
    886     }
    887 
    888     {
    889         static jfieldID effective_fid = env->GetFieldID(data_class.get(), "effective", "I");
    890         if (effective_fid == nullptr) {
    891             return false;
    892         }
    893         c_data->effective = env->GetIntField(java_data, effective_fid);
    894     }
    895 
    896     {
    897         static jfieldID permitted_fid = env->GetFieldID(data_class.get(), "permitted", "I");
    898         if (permitted_fid == nullptr) {
    899             return false;
    900         }
    901         c_data->permitted = env->GetIntField(java_data, permitted_fid);
    902     }
    903 
    904 
    905     {
    906         static jfieldID inheritable_fid = env->GetFieldID(data_class.get(), "inheritable", "I");
    907         if (inheritable_fid == nullptr) {
    908             return false;
    909         }
    910         c_data->inheritable = env->GetIntField(java_data, inheritable_fid);
    911     }
    912 
    913     return true;
    914 }
    915 
    916 static constexpr size_t kMaxCapUserDataLength = 2U;
    917 #ifdef _LINUX_CAPABILITY_VERSION_1
    918 static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_1, "Length too small.");
    919 #endif
    920 #ifdef _LINUX_CAPABILITY_VERSION_2
    921 static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_2, "Length too small.");
    922 #endif
    923 #ifdef _LINUX_CAPABILITY_VERSION_3
    924 static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_3, "Length too small.");
    925 #endif
    926 #ifdef _LINUX_CAPABILITY_VERSION_4
    927 static_assert(false, "Unsupported capability version, please update.");
    928 #endif
    929 
    930 static size_t GetCapUserDataLength(uint32_t version) {
    931 #ifdef _LINUX_CAPABILITY_VERSION_1
    932     if (version == _LINUX_CAPABILITY_VERSION_1) {
    933         return _LINUX_CAPABILITY_U32S_1;
    934     }
    935 #endif
    936 #ifdef _LINUX_CAPABILITY_VERSION_2
    937     if (version == _LINUX_CAPABILITY_VERSION_2) {
    938         return _LINUX_CAPABILITY_U32S_2;
    939     }
    940 #endif
    941 #ifdef _LINUX_CAPABILITY_VERSION_3
    942     if (version == _LINUX_CAPABILITY_VERSION_3) {
    943         return _LINUX_CAPABILITY_U32S_3;
    944     }
    945 #endif
    946     return 0;
    947 }
    948 
    949 static jobject Linux_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
    950     sockaddr_storage ss;
    951     socklen_t sl = sizeof(ss);
    952     memset(&ss, 0, sizeof(ss));
    953     sockaddr* peer = (javaSocketAddress != NULL) ? reinterpret_cast<sockaddr*>(&ss) : NULL;
    954     socklen_t* peerLength = (javaSocketAddress != NULL) ? &sl : 0;
    955     jint clientFd = NET_FAILURE_RETRY(env, int, accept, javaFd, peer, peerLength);
    956     if (clientFd == -1 || !fillSocketAddress(env, javaSocketAddress, ss, *peerLength)) {
    957         close(clientFd);
    958         return NULL;
    959     }
    960     return (clientFd != -1) ? jniCreateFileDescriptor(env, clientFd) : NULL;
    961 }
    962 
    963 static jboolean Linux_access(JNIEnv* env, jobject, jstring javaPath, jint mode) {
    964     ScopedUtfChars path(env, javaPath);
    965     if (path.c_str() == NULL) {
    966         return JNI_FALSE;
    967     }
    968     int rc = TEMP_FAILURE_RETRY(access(path.c_str(), mode));
    969     if (rc == -1) {
    970         throwErrnoException(env, "access");
    971     }
    972     return (rc == 0);
    973 }
    974 
    975 static void Linux_bind(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
    976     // We don't need the return value because we'll already have thrown.
    977     (void) NET_IPV4_FALLBACK(env, int, bind, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN);
    978 }
    979 
    980 static void Linux_bindSocketAddress(
    981         JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
    982     sockaddr_storage ss;
    983     socklen_t sa_len;
    984     if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
    985         return;  // Exception already thrown.
    986     }
    987 
    988     const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss);
    989     // We don't need the return value because we'll already have thrown.
    990     (void) NET_FAILURE_RETRY(env, int, bind, javaFd, sa, sa_len);
    991 }
    992 
    993 static jobjectArray Linux_capget(JNIEnv* env, jobject, jobject header) {
    994     // Convert Java header struct to kernel datastructure.
    995     __user_cap_header_struct cap_header;
    996     if (!ReadStructCapUserHeader(env, header, &cap_header)) {
    997         AssertException(env);
    998         return nullptr;
    999     }
   1000 
   1001     // Call capget.
   1002     __user_cap_data_struct cap_data[kMaxCapUserDataLength];
   1003     if (capget(&cap_header, &cap_data[0]) == -1) {
   1004         // Check for EINVAL. In that case, mutate the header.
   1005         if (errno == EINVAL) {
   1006             int saved_errno = errno;
   1007             SetStructCapUserHeaderVersion(env, header, &cap_header);
   1008             errno = saved_errno;
   1009         }
   1010         throwErrnoException(env, "capget");
   1011         return nullptr;
   1012     }
   1013 
   1014     // Create the result array.
   1015     ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
   1016     if (data_class.get() == nullptr) {
   1017         return nullptr;
   1018     }
   1019     size_t result_size = GetCapUserDataLength(cap_header.version);
   1020     ScopedLocalRef<jobjectArray> result(
   1021             env, env->NewObjectArray(result_size, data_class.get(), nullptr));
   1022     if (result.get() == nullptr) {
   1023         return nullptr;
   1024     }
   1025     // Translate the values we got.
   1026     for (size_t i = 0; i < result_size; ++i) {
   1027         ScopedLocalRef<jobject> value(
   1028                 env, CreateStructCapUserData(env, data_class.get(), &cap_data[i]));
   1029         if (value.get() == nullptr) {
   1030             AssertException(env);
   1031             return nullptr;
   1032         }
   1033         env->SetObjectArrayElement(result.get(), i, value.get());
   1034     }
   1035     return result.release();
   1036 }
   1037 
   1038 static void Linux_capset(
   1039         JNIEnv* env, jobject, jobject header, jobjectArray data) {
   1040     // Convert Java header struct to kernel datastructure.
   1041     __user_cap_header_struct cap_header;
   1042     if (!ReadStructCapUserHeader(env, header, &cap_header)) {
   1043         AssertException(env);
   1044         return;
   1045     }
   1046     size_t result_size = GetCapUserDataLength(cap_header.version);
   1047     // Ensure that the array has the expected length.
   1048     if (env->GetArrayLength(data) != static_cast<jint>(result_size)) {
   1049         jniThrowExceptionFmt(env,
   1050                              "java/lang/IllegalArgumentException",
   1051                              "Unsupported input length %d (expected %zu)",
   1052                              env->GetArrayLength(data),
   1053                              result_size);
   1054         return;
   1055     }
   1056 
   1057     __user_cap_data_struct cap_data[kMaxCapUserDataLength];
   1058     // Translate the values we got.
   1059     for (size_t i = 0; i < result_size; ++i) {
   1060         ScopedLocalRef<jobject> value(env, env->GetObjectArrayElement(data, i));
   1061         if (!ReadStructCapUserData(env, value.get(), &cap_data[i])) {
   1062             AssertException(env);
   1063             return;
   1064         }
   1065     }
   1066 
   1067     throwIfMinusOne(env, "capset", capset(&cap_header, &cap_data[0]));
   1068 }
   1069 
   1070 static void Linux_chmod(JNIEnv* env, jobject, jstring javaPath, jint mode) {
   1071     ScopedUtfChars path(env, javaPath);
   1072     if (path.c_str() == NULL) {
   1073         return;
   1074     }
   1075     throwIfMinusOne(env, "chmod", TEMP_FAILURE_RETRY(chmod(path.c_str(), mode)));
   1076 }
   1077 
   1078 static void Linux_chown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
   1079     ScopedUtfChars path(env, javaPath);
   1080     if (path.c_str() == NULL) {
   1081         return;
   1082     }
   1083     throwIfMinusOne(env, "chown", TEMP_FAILURE_RETRY(chown(path.c_str(), uid, gid)));
   1084 }
   1085 
   1086 static void Linux_close(JNIEnv* env, jobject, jobject javaFd) {
   1087     // Get the FileDescriptor's 'fd' field and clear it.
   1088     // We need to do this before we can throw an IOException (http://b/3222087).
   1089     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1090     jniSetFileDescriptorOfFD(env, javaFd, -1);
   1091 
   1092     // Even if close(2) fails with EINTR, the fd will have been closed.
   1093     // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone else's fd.
   1094     // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
   1095     throwIfMinusOne(env, "close", close(fd));
   1096 }
   1097 
   1098 static void Linux_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
   1099     (void) NET_IPV4_FALLBACK(env, int, connect, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN);
   1100 }
   1101 
   1102 static void Linux_connectSocketAddress(
   1103         JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
   1104     sockaddr_storage ss;
   1105     socklen_t sa_len;
   1106     if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
   1107         return;  // Exception already thrown.
   1108     }
   1109 
   1110     const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss);
   1111     // We don't need the return value because we'll already have thrown.
   1112     (void) NET_FAILURE_RETRY(env, int, connect, javaFd, sa, sa_len);
   1113 }
   1114 
   1115 static jobject Linux_dup(JNIEnv* env, jobject, jobject javaOldFd) {
   1116     int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
   1117     int newFd = throwIfMinusOne(env, "dup", TEMP_FAILURE_RETRY(dup(oldFd)));
   1118     return (newFd != -1) ? jniCreateFileDescriptor(env, newFd) : NULL;
   1119 }
   1120 
   1121 static jobject Linux_dup2(JNIEnv* env, jobject, jobject javaOldFd, jint newFd) {
   1122     int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
   1123     int fd = throwIfMinusOne(env, "dup2", TEMP_FAILURE_RETRY(dup2(oldFd, newFd)));
   1124     return (fd != -1) ? jniCreateFileDescriptor(env, fd) : NULL;
   1125 }
   1126 
   1127 static jobjectArray Linux_environ(JNIEnv* env, jobject) {
   1128     extern char** environ; // Standard, but not in any header file.
   1129     return toStringArray(env, environ);
   1130 }
   1131 
   1132 static void Linux_execve(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv, jobjectArray javaEnvp) {
   1133     ScopedUtfChars path(env, javaFilename);
   1134     if (path.c_str() == NULL) {
   1135         return;
   1136     }
   1137 
   1138     ExecStrings argv(env, javaArgv);
   1139     ExecStrings envp(env, javaEnvp);
   1140     TEMP_FAILURE_RETRY(execve(path.c_str(), argv.get(), envp.get()));
   1141 
   1142     throwErrnoException(env, "execve");
   1143 }
   1144 
   1145 static void Linux_execv(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv) {
   1146     ScopedUtfChars path(env, javaFilename);
   1147     if (path.c_str() == NULL) {
   1148         return;
   1149     }
   1150 
   1151     ExecStrings argv(env, javaArgv);
   1152     TEMP_FAILURE_RETRY(execv(path.c_str(), argv.get()));
   1153 
   1154     throwErrnoException(env, "execv");
   1155 }
   1156 
   1157 static void Linux_fchmod(JNIEnv* env, jobject, jobject javaFd, jint mode) {
   1158     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1159     throwIfMinusOne(env, "fchmod", TEMP_FAILURE_RETRY(fchmod(fd, mode)));
   1160 }
   1161 
   1162 static void Linux_fchown(JNIEnv* env, jobject, jobject javaFd, jint uid, jint gid) {
   1163     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1164     throwIfMinusOne(env, "fchown", TEMP_FAILURE_RETRY(fchown(fd, uid, gid)));
   1165 }
   1166 
   1167 static jint Linux_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaFlock) {
   1168     static jfieldID typeFid = env->GetFieldID(JniConstants::structFlockClass, "l_type", "S");
   1169     static jfieldID whenceFid = env->GetFieldID(JniConstants::structFlockClass, "l_whence", "S");
   1170     static jfieldID startFid = env->GetFieldID(JniConstants::structFlockClass, "l_start", "J");
   1171     static jfieldID lenFid = env->GetFieldID(JniConstants::structFlockClass, "l_len", "J");
   1172     static jfieldID pidFid = env->GetFieldID(JniConstants::structFlockClass, "l_pid", "I");
   1173 
   1174     struct flock64 lock;
   1175     memset(&lock, 0, sizeof(lock));
   1176     lock.l_type = env->GetShortField(javaFlock, typeFid);
   1177     lock.l_whence = env->GetShortField(javaFlock, whenceFid);
   1178     lock.l_start = env->GetLongField(javaFlock, startFid);
   1179     lock.l_len = env->GetLongField(javaFlock, lenFid);
   1180     lock.l_pid = env->GetIntField(javaFlock, pidFid);
   1181 
   1182     int rc = IO_FAILURE_RETRY(env, int, fcntl, javaFd, cmd, &lock);
   1183     if (rc != -1) {
   1184         env->SetShortField(javaFlock, typeFid, lock.l_type);
   1185         env->SetShortField(javaFlock, whenceFid, lock.l_whence);
   1186         env->SetLongField(javaFlock, startFid, lock.l_start);
   1187         env->SetLongField(javaFlock, lenFid, lock.l_len);
   1188         env->SetIntField(javaFlock, pidFid, lock.l_pid);
   1189     }
   1190     return rc;
   1191 }
   1192 
   1193 static jint Linux_fcntlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jint arg) {
   1194     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1195     return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd, arg)));
   1196 }
   1197 
   1198 static jint Linux_fcntlVoid(JNIEnv* env, jobject, jobject javaFd, jint cmd) {
   1199     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1200     return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd)));
   1201 }
   1202 
   1203 static void Linux_fdatasync(JNIEnv* env, jobject, jobject javaFd) {
   1204     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1205     throwIfMinusOne(env, "fdatasync", TEMP_FAILURE_RETRY(fdatasync(fd)));
   1206 }
   1207 
   1208 static jobject Linux_fstat(JNIEnv* env, jobject, jobject javaFd) {
   1209     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1210     struct stat64 sb;
   1211     int rc = TEMP_FAILURE_RETRY(fstat64(fd, &sb));
   1212     if (rc == -1) {
   1213         throwErrnoException(env, "fstat");
   1214         return NULL;
   1215     }
   1216     return makeStructStat(env, sb);
   1217 }
   1218 
   1219 static jobject Linux_fstatvfs(JNIEnv* env, jobject, jobject javaFd) {
   1220     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1221     struct statvfs sb;
   1222     int rc = TEMP_FAILURE_RETRY(fstatvfs(fd, &sb));
   1223     if (rc == -1) {
   1224         throwErrnoException(env, "fstatvfs");
   1225         return NULL;
   1226     }
   1227     return makeStructStatVfs(env, sb);
   1228 }
   1229 
   1230 static void Linux_fsync(JNIEnv* env, jobject, jobject javaFd) {
   1231     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1232     throwIfMinusOne(env, "fsync", TEMP_FAILURE_RETRY(fsync(fd)));
   1233 }
   1234 
   1235 static void Linux_ftruncate(JNIEnv* env, jobject, jobject javaFd, jlong length) {
   1236     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1237     throwIfMinusOne(env, "ftruncate", TEMP_FAILURE_RETRY(ftruncate64(fd, length)));
   1238 }
   1239 
   1240 static jstring Linux_gai_strerror(JNIEnv* env, jobject, jint error) {
   1241     return env->NewStringUTF(gai_strerror(error));
   1242 }
   1243 
   1244 static jobjectArray Linux_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,
   1245         jobject javaHints, jint netId) {
   1246     ScopedUtfChars node(env, javaNode);
   1247     if (node.c_str() == NULL) {
   1248         return NULL;
   1249     }
   1250 
   1251     static jfieldID flagsFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_flags", "I");
   1252     static jfieldID familyFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_family", "I");
   1253     static jfieldID socktypeFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_socktype", "I");
   1254     static jfieldID protocolFid = env->GetFieldID(JniConstants::structAddrinfoClass, "ai_protocol", "I");
   1255 
   1256     addrinfo hints;
   1257     memset(&hints, 0, sizeof(hints));
   1258     hints.ai_flags = env->GetIntField(javaHints, flagsFid);
   1259     hints.ai_family = env->GetIntField(javaHints, familyFid);
   1260     hints.ai_socktype = env->GetIntField(javaHints, socktypeFid);
   1261     hints.ai_protocol = env->GetIntField(javaHints, protocolFid);
   1262 
   1263     addrinfo* addressList = NULL;
   1264     errno = 0;
   1265     int rc = android_getaddrinfofornet(node.c_str(), NULL, &hints, netId, 0, &addressList);
   1266     std::unique_ptr<addrinfo, addrinfo_deleter> addressListDeleter(addressList);
   1267     if (rc != 0) {
   1268         throwGaiException(env, "android_getaddrinfo", rc);
   1269         return NULL;
   1270     }
   1271 
   1272     // Count results so we know how to size the output array.
   1273     int addressCount = 0;
   1274     for (addrinfo* ai = addressList; ai != NULL; ai = ai->ai_next) {
   1275         if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6) {
   1276             ++addressCount;
   1277         } else {
   1278             ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);
   1279         }
   1280     }
   1281     if (addressCount == 0) {
   1282         return NULL;
   1283     }
   1284 
   1285     // Prepare output array.
   1286     jobjectArray result = env->NewObjectArray(addressCount, JniConstants::inetAddressClass, NULL);
   1287     if (result == NULL) {
   1288         return NULL;
   1289     }
   1290 
   1291     // Examine returned addresses one by one, save them in the output array.
   1292     int index = 0;
   1293     for (addrinfo* ai = addressList; ai != NULL; ai = ai->ai_next) {
   1294         if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
   1295             // Unknown address family. Skip this address.
   1296             ALOGE("android_getaddrinfo unexpected ai_family %i", ai->ai_family);
   1297             continue;
   1298         }
   1299 
   1300         // Convert each IP address into a Java byte array.
   1301         sockaddr_storage& address = *reinterpret_cast<sockaddr_storage*>(ai->ai_addr);
   1302         ScopedLocalRef<jobject> inetAddress(env, sockaddrToInetAddress(env, address, NULL));
   1303         if (inetAddress.get() == NULL) {
   1304             return NULL;
   1305         }
   1306         env->SetObjectArrayElement(result, index, inetAddress.get());
   1307         ++index;
   1308     }
   1309     return result;
   1310 }
   1311 
   1312 static jint Linux_getegid(JNIEnv*, jobject) {
   1313     return getegid();
   1314 }
   1315 
   1316 static jint Linux_geteuid(JNIEnv*, jobject) {
   1317     return geteuid();
   1318 }
   1319 
   1320 static jint Linux_getgid(JNIEnv*, jobject) {
   1321     return getgid();
   1322 }
   1323 
   1324 static jstring Linux_getenv(JNIEnv* env, jobject, jstring javaName) {
   1325     ScopedUtfChars name(env, javaName);
   1326     if (name.c_str() == NULL) {
   1327         return NULL;
   1328     }
   1329     return env->NewStringUTF(getenv(name.c_str()));
   1330 }
   1331 
   1332 static jstring Linux_getnameinfo(JNIEnv* env, jobject, jobject javaAddress, jint flags) {
   1333     sockaddr_storage ss;
   1334     socklen_t sa_len;
   1335     if (!inetAddressToSockaddrVerbatim(env, javaAddress, 0, ss, sa_len)) {
   1336         return NULL;
   1337     }
   1338     char buf[NI_MAXHOST]; // NI_MAXHOST is longer than INET6_ADDRSTRLEN.
   1339     errno = 0;
   1340     int rc = getnameinfo(reinterpret_cast<sockaddr*>(&ss), sa_len, buf, sizeof(buf), NULL, 0, flags);
   1341     if (rc != 0) {
   1342         throwGaiException(env, "getnameinfo", rc);
   1343         return NULL;
   1344     }
   1345     return env->NewStringUTF(buf);
   1346 }
   1347 
   1348 static jobject Linux_getpeername(JNIEnv* env, jobject, jobject javaFd) {
   1349   return doGetSockName(env, javaFd, false);
   1350 }
   1351 
   1352 static jint Linux_getpgid(JNIEnv* env, jobject, jint pid) {
   1353     return throwIfMinusOne(env, "getpgid", TEMP_FAILURE_RETRY(getpgid(pid)));
   1354 }
   1355 
   1356 static jint Linux_getpid(JNIEnv*, jobject) {
   1357     return TEMP_FAILURE_RETRY(getpid());
   1358 }
   1359 
   1360 static jint Linux_getppid(JNIEnv*, jobject) {
   1361     return TEMP_FAILURE_RETRY(getppid());
   1362 }
   1363 
   1364 static jobject Linux_getpwnam(JNIEnv* env, jobject, jstring javaName) {
   1365     ScopedUtfChars name(env, javaName);
   1366     if (name.c_str() == NULL) {
   1367         return NULL;
   1368     }
   1369     return Passwd(env).getpwnam(name.c_str());
   1370 }
   1371 
   1372 static jobject Linux_getpwuid(JNIEnv* env, jobject, jint uid) {
   1373     return Passwd(env).getpwuid(uid);
   1374 }
   1375 
   1376 static jobject Linux_getrlimit(JNIEnv* env, jobject, jint resource) {
   1377     struct rlimit r;
   1378     if (throwIfMinusOne(env, "getrlimit", TEMP_FAILURE_RETRY(getrlimit(resource, &r))) == -1) {
   1379         return nullptr;
   1380     }
   1381 
   1382     ScopedLocalRef<jclass> rlimit_class(env, env->FindClass("android/system/StructRlimit"));
   1383     jmethodID ctor = env->GetMethodID(rlimit_class.get(), "<init>", "(JJ)V");
   1384     if (ctor == NULL) {
   1385         return NULL;
   1386     }
   1387     return env->NewObject(rlimit_class.get(), ctor,
   1388                           static_cast<jlong>(r.rlim_cur),
   1389                           static_cast<jlong>(r.rlim_max));
   1390 }
   1391 
   1392 static jobject Linux_getsockname(JNIEnv* env, jobject, jobject javaFd) {
   1393   return doGetSockName(env, javaFd, true);
   1394 }
   1395 
   1396 static jint Linux_getsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
   1397     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1398     u_char result = 0;
   1399     socklen_t size = sizeof(result);
   1400     throwIfMinusOne(env, "getsockopt", TEMP_FAILURE_RETRY(getsockopt(fd, level, option, &result, &size)));
   1401     return result;
   1402 }
   1403 
   1404 static jobject Linux_getsockoptInAddr(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
   1405     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1406     sockaddr_storage ss;
   1407     memset(&ss, 0, sizeof(ss));
   1408     ss.ss_family = AF_INET; // This is only for the IPv4-only IP_MULTICAST_IF.
   1409     sockaddr_in* sa = reinterpret_cast<sockaddr_in*>(&ss);
   1410     socklen_t size = sizeof(sa->sin_addr);
   1411     int rc = TEMP_FAILURE_RETRY(getsockopt(fd, level, option, &sa->sin_addr, &size));
   1412     if (rc == -1) {
   1413         throwErrnoException(env, "getsockopt");
   1414         return NULL;
   1415     }
   1416     return sockaddrToInetAddress(env, ss, NULL);
   1417 }
   1418 
   1419 static jint Linux_getsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
   1420     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1421     jint result = 0;
   1422     socklen_t size = sizeof(result);
   1423     throwIfMinusOne(env, "getsockopt", TEMP_FAILURE_RETRY(getsockopt(fd, level, option, &result, &size)));
   1424     return result;
   1425 }
   1426 
   1427 static jobject Linux_getsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
   1428     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1429     struct linger l;
   1430     socklen_t size = sizeof(l);
   1431     memset(&l, 0, size);
   1432     int rc = TEMP_FAILURE_RETRY(getsockopt(fd, level, option, &l, &size));
   1433     if (rc == -1) {
   1434         throwErrnoException(env, "getsockopt");
   1435         return NULL;
   1436     }
   1437     return makeStructLinger(env, l);
   1438 }
   1439 
   1440 static jobject Linux_getsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
   1441     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1442     struct timeval tv;
   1443     socklen_t size = sizeof(tv);
   1444     memset(&tv, 0, size);
   1445     int rc = TEMP_FAILURE_RETRY(getsockopt(fd, level, option, &tv, &size));
   1446     if (rc == -1) {
   1447         throwErrnoException(env, "getsockopt");
   1448         return NULL;
   1449     }
   1450     return makeStructTimeval(env, tv);
   1451 }
   1452 
   1453 static jobject Linux_getsockoptUcred(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
   1454   int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1455   struct ucred u;
   1456   socklen_t size = sizeof(u);
   1457   memset(&u, 0, size);
   1458   int rc = TEMP_FAILURE_RETRY(getsockopt(fd, level, option, &u, &size));
   1459   if (rc == -1) {
   1460     throwErrnoException(env, "getsockopt");
   1461     return NULL;
   1462   }
   1463   return makeStructUcred(env, u);
   1464 }
   1465 
   1466 static jint Linux_gettid(JNIEnv* env __unused, jobject) {
   1467 #if defined(__BIONIC__)
   1468   return TEMP_FAILURE_RETRY(gettid());
   1469 #else
   1470   return syscall(__NR_gettid);
   1471 #endif
   1472 }
   1473 
   1474 static jint Linux_getuid(JNIEnv*, jobject) {
   1475     return getuid();
   1476 }
   1477 
   1478 static jbyteArray Linux_getxattr(JNIEnv* env, jobject, jstring javaPath,
   1479         jstring javaName) {
   1480     ScopedUtfChars path(env, javaPath);
   1481     if (path.c_str() == NULL) {
   1482         return NULL;
   1483     }
   1484     ScopedUtfChars name(env, javaName);
   1485     if (name.c_str() == NULL) {
   1486         return NULL;
   1487     }
   1488 
   1489     while (true) {
   1490         // Get the current size of the named extended attribute.
   1491         ssize_t valueLength;
   1492         if ((valueLength = getxattr(path.c_str(), name.c_str(), NULL, 0)) < 0) {
   1493             throwErrnoException(env, "getxattr");
   1494             return NULL;
   1495         }
   1496 
   1497         // Create the actual byte array.
   1498         std::vector<char> buf(valueLength);
   1499         if ((valueLength = getxattr(path.c_str(), name.c_str(), buf.data(), valueLength)) < 0) {
   1500             if (errno == ERANGE) {
   1501                 // The attribute value has changed since last getxattr call and buf no longer fits,
   1502                 // try again.
   1503                 continue;
   1504             }
   1505             throwErrnoException(env, "getxattr");
   1506             return NULL;
   1507         }
   1508         jbyteArray array = env->NewByteArray(valueLength);
   1509         if (array == NULL) {
   1510             return NULL;
   1511         }
   1512         env->SetByteArrayRegion(array, 0, valueLength, reinterpret_cast<const jbyte*>(buf.data()));
   1513         return array;
   1514     }
   1515 }
   1516 
   1517 static jobjectArray Linux_getifaddrs(JNIEnv* env, jobject) {
   1518     static jmethodID ctor = env->GetMethodID(JniConstants::structIfaddrs, "<init>",
   1519             "(Ljava/lang/String;ILjava/net/InetAddress;Ljava/net/InetAddress;Ljava/net/InetAddress;[B)V");
   1520     if (ctor == NULL) {
   1521         return NULL;
   1522     }
   1523 
   1524     ifaddrs* ifaddr;
   1525     int rc = TEMP_FAILURE_RETRY(getifaddrs(&ifaddr));
   1526     if (rc == -1) {
   1527         throwErrnoException(env, "getifaddrs");
   1528         return NULL;
   1529     }
   1530     std::unique_ptr<ifaddrs, decltype(&freeifaddrs)> ifaddrPtr(ifaddr, freeifaddrs);
   1531 
   1532     // Count results so we know how to size the output array.
   1533     jint ifCount = 0;
   1534     for (ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
   1535         ++ifCount;
   1536     }
   1537 
   1538     // Prepare output array.
   1539     jobjectArray result = env->NewObjectArray(ifCount, JniConstants::structIfaddrs, NULL);
   1540     if (result == NULL) {
   1541         return NULL;
   1542     }
   1543 
   1544     // Traverse the list and populate the output array.
   1545     int index = 0;
   1546     for (ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next, ++index) {
   1547         TO_JAVA_STRING(name, ifa->ifa_name);
   1548         jint flags = ifa->ifa_flags;
   1549         sockaddr_storage* interfaceAddr =
   1550             reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr);
   1551         sockaddr_storage* netmaskAddr =
   1552             reinterpret_cast<sockaddr_storage*>(ifa->ifa_netmask);
   1553         sockaddr_storage* broadAddr =
   1554             reinterpret_cast<sockaddr_storage*>(ifa->ifa_broadaddr);
   1555 
   1556         jobject addr, netmask, broad;
   1557         jbyteArray hwaddr = NULL;
   1558         if (interfaceAddr != NULL) {
   1559             switch (interfaceAddr->ss_family) {
   1560             case AF_INET:
   1561             case AF_INET6:
   1562                 // IPv4 / IPv6.
   1563                 // interfaceAddr and netmaskAddr are never null.
   1564                 if ((addr = sockaddrToInetAddress(env, *interfaceAddr, NULL)) == NULL) {
   1565                     return NULL;
   1566                 }
   1567                 if ((netmask = sockaddrToInetAddress(env, *netmaskAddr, NULL)) == NULL) {
   1568                     return NULL;
   1569                 }
   1570                 if (broadAddr != NULL && (ifa->ifa_flags & IFF_BROADCAST)) {
   1571                     if ((broad = sockaddrToInetAddress(env, *broadAddr, NULL)) == NULL) {
   1572                         return NULL;
   1573                     }
   1574                 } else {
   1575                     broad = NULL;
   1576                 }
   1577                 break;
   1578             case AF_PACKET:
   1579                 // Raw Interface.
   1580                 sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(ifa->ifa_addr);
   1581 
   1582                 bool allZero = true;
   1583                 for (int i = 0; i < sll->sll_halen; ++i) {
   1584                     if (sll->sll_addr[i] != 0) {
   1585                         allZero = false;
   1586                         break;
   1587                     }
   1588                 }
   1589 
   1590                 if (!allZero) {
   1591                     hwaddr = env->NewByteArray(sll->sll_halen);
   1592                     if (hwaddr == NULL) {
   1593                         return NULL;
   1594                     }
   1595                     env->SetByteArrayRegion(hwaddr, 0, sll->sll_halen,
   1596                                             reinterpret_cast<const jbyte*>(sll->sll_addr));
   1597                 }
   1598                 addr = netmask = broad = NULL;
   1599                 break;
   1600             }
   1601         } else {
   1602             // Preserve the entry even if the interface has no interface address.
   1603             // http://b/29243557/
   1604             addr = netmask = broad = NULL;
   1605         }
   1606 
   1607         jobject o = env->NewObject(JniConstants::structIfaddrs, ctor, name, flags, addr, netmask,
   1608                                    broad, hwaddr);
   1609         if (o == NULL) {
   1610             return NULL;
   1611         }
   1612         env->SetObjectArrayElement(result, index, o);
   1613     }
   1614 
   1615     return result;
   1616 }
   1617 
   1618 static jstring Linux_if_indextoname(JNIEnv* env, jobject, jint index) {
   1619     char buf[IF_NAMESIZE];
   1620     char* name = if_indextoname(index, buf);
   1621     // if_indextoname(3) returns NULL on failure, which will come out of NewStringUTF unscathed.
   1622     // There's no useful information in errno, so we don't bother throwing. Callers can null-check.
   1623     return env->NewStringUTF(name);
   1624 }
   1625 
   1626 static jint Linux_if_nametoindex(JNIEnv* env, jobject, jstring name) {
   1627     ScopedUtfChars cname(env, name);
   1628     if (cname.c_str() == NULL) {
   1629         return 0;
   1630     }
   1631 
   1632     // There's no useful information in errno, so we don't bother throwing. Callers can zero-check.
   1633     return if_nametoindex(cname.c_str());
   1634 }
   1635 
   1636 static jobject Linux_inet_pton(JNIEnv* env, jobject, jint family, jstring javaName) {
   1637     ScopedUtfChars name(env, javaName);
   1638     if (name.c_str() == NULL) {
   1639         return NULL;
   1640     }
   1641     sockaddr_storage ss;
   1642     memset(&ss, 0, sizeof(ss));
   1643     // sockaddr_in and sockaddr_in6 are at the same address, so we can use either here.
   1644     void* dst = &reinterpret_cast<sockaddr_in*>(&ss)->sin_addr;
   1645     if (inet_pton(family, name.c_str(), dst) != 1) {
   1646         return NULL;
   1647     }
   1648     ss.ss_family = family;
   1649     return sockaddrToInetAddress(env, ss, NULL);
   1650 }
   1651 
   1652 static jint Linux_ioctlFlags(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
   1653      struct ifreq req;
   1654      if (!fillIfreq(env, javaInterfaceName, req)) {
   1655         return 0;
   1656      }
   1657      int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1658      throwIfMinusOne(env, "ioctl", TEMP_FAILURE_RETRY(ioctl(fd, SIOCGIFFLAGS, &req)));
   1659      return req.ifr_flags;
   1660 }
   1661 
   1662 static jobject Linux_ioctlInetAddress(JNIEnv* env, jobject, jobject javaFd, jint cmd, jstring javaInterfaceName) {
   1663     struct ifreq req;
   1664     if (!fillIfreq(env, javaInterfaceName, req)) {
   1665         return NULL;
   1666     }
   1667     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1668     int rc = throwIfMinusOne(env, "ioctl", TEMP_FAILURE_RETRY(ioctl(fd, cmd, &req)));
   1669     if (rc == -1) {
   1670         return NULL;
   1671     }
   1672     return sockaddrToInetAddress(env, reinterpret_cast<sockaddr_storage&>(req.ifr_addr), NULL);
   1673 }
   1674 
   1675 static jint Linux_ioctlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaArg) {
   1676     // This is complicated because ioctls may return their result by updating their argument
   1677     // or via their return value, so we need to support both.
   1678     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1679     jint arg = env->GetIntField(javaArg, int32RefValueFid);
   1680     int rc = throwIfMinusOne(env, "ioctl", TEMP_FAILURE_RETRY(ioctl(fd, cmd, &arg)));
   1681     if (!env->ExceptionCheck()) {
   1682         env->SetIntField(javaArg, int32RefValueFid, arg);
   1683     }
   1684     return rc;
   1685 }
   1686 
   1687 static jint Linux_ioctlMTU(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
   1688      struct ifreq req;
   1689      if (!fillIfreq(env, javaInterfaceName, req)) {
   1690         return 0;
   1691      }
   1692      int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1693      throwIfMinusOne(env, "ioctl", TEMP_FAILURE_RETRY(ioctl(fd, SIOCGIFMTU, &req)));
   1694      return req.ifr_mtu;
   1695 }
   1696 
   1697 static jboolean Linux_isatty(JNIEnv* env, jobject, jobject javaFd) {
   1698     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1699     return TEMP_FAILURE_RETRY(isatty(fd)) == 1;
   1700 }
   1701 
   1702 static void Linux_kill(JNIEnv* env, jobject, jint pid, jint sig) {
   1703     throwIfMinusOne(env, "kill", TEMP_FAILURE_RETRY(kill(pid, sig)));
   1704 }
   1705 
   1706 static void Linux_lchown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
   1707     ScopedUtfChars path(env, javaPath);
   1708     if (path.c_str() == NULL) {
   1709         return;
   1710     }
   1711     throwIfMinusOne(env, "lchown", TEMP_FAILURE_RETRY(lchown(path.c_str(), uid, gid)));
   1712 }
   1713 
   1714 static void Linux_link(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
   1715     ScopedUtfChars oldPath(env, javaOldPath);
   1716     if (oldPath.c_str() == NULL) {
   1717         return;
   1718     }
   1719     ScopedUtfChars newPath(env, javaNewPath);
   1720     if (newPath.c_str() == NULL) {
   1721         return;
   1722     }
   1723     throwIfMinusOne(env, "link", TEMP_FAILURE_RETRY(link(oldPath.c_str(), newPath.c_str())));
   1724 }
   1725 
   1726 static void Linux_listen(JNIEnv* env, jobject, jobject javaFd, jint backlog) {
   1727     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1728     throwIfMinusOne(env, "listen", TEMP_FAILURE_RETRY(listen(fd, backlog)));
   1729 }
   1730 
   1731 static jobjectArray Linux_listxattr(JNIEnv* env, jobject, jstring javaPath) {
   1732     ScopedUtfChars path(env, javaPath);
   1733     if (path.c_str() == NULL) {
   1734         return NULL;
   1735     }
   1736 
   1737     while (true) {
   1738         // Get the current size of the named extended attribute.
   1739         ssize_t valueLength;
   1740         if ((valueLength = listxattr(path.c_str(), NULL, 0)) < 0) {
   1741             throwErrnoException(env, "listxattr");
   1742             return NULL;
   1743         }
   1744 
   1745         // Create the actual byte array.
   1746         std::string buf(valueLength, '\0');
   1747         if ((valueLength = listxattr(path.c_str(), &buf[0], valueLength)) < 0) {
   1748             if (errno == ERANGE) {
   1749                 // The attribute value has changed since last listxattr call and buf no longer fits,
   1750                 // try again.
   1751                 continue;
   1752             }
   1753             throwErrnoException(env, "listxattr");
   1754             return NULL;
   1755         }
   1756 
   1757         // Split the output by '\0'.
   1758         buf.resize(valueLength > 0 ? valueLength - 1 : 0); // Remove the trailing NULL character.
   1759         std::string delim("\0", 1);
   1760         auto xattrs = android::base::Split(buf, delim);
   1761 
   1762         return toStringArray(env, xattrs);
   1763     }
   1764 }
   1765 
   1766 static jlong Linux_lseek(JNIEnv* env, jobject, jobject javaFd, jlong offset, jint whence) {
   1767     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1768     return throwIfMinusOne(env, "lseek", TEMP_FAILURE_RETRY(lseek64(fd, offset, whence)));
   1769 }
   1770 
   1771 static jobject Linux_lstat(JNIEnv* env, jobject, jstring javaPath) {
   1772     return doStat(env, javaPath, true);
   1773 }
   1774 
   1775 static void Linux_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) {
   1776     ScopedByteArrayRW vector(env, javaVector);
   1777     if (vector.get() == NULL) {
   1778         return;
   1779     }
   1780     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
   1781     unsigned char* vec = reinterpret_cast<unsigned char*>(vector.get());
   1782     throwIfMinusOne(env, "mincore", TEMP_FAILURE_RETRY(mincore(ptr, byteCount, vec)));
   1783 }
   1784 
   1785 static void Linux_mkdir(JNIEnv* env, jobject, jstring javaPath, jint mode) {
   1786     ScopedUtfChars path(env, javaPath);
   1787     if (path.c_str() == NULL) {
   1788         return;
   1789     }
   1790     throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), mode)));
   1791 }
   1792 
   1793 static void Linux_mkfifo(JNIEnv* env, jobject, jstring javaPath, jint mode) {
   1794     ScopedUtfChars path(env, javaPath);
   1795     if (path.c_str() == NULL) {
   1796         return;
   1797     }
   1798     throwIfMinusOne(env, "mkfifo", TEMP_FAILURE_RETRY(mkfifo(path.c_str(), mode)));
   1799 }
   1800 
   1801 static void Linux_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
   1802     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
   1803     throwIfMinusOne(env, "mlock", TEMP_FAILURE_RETRY(mlock(ptr, byteCount)));
   1804 }
   1805 
   1806 static jlong Linux_mmap(JNIEnv* env, jobject, jlong address, jlong byteCount, jint prot, jint flags, jobject javaFd, jlong offset) {
   1807     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1808     void* suggestedPtr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
   1809     void* ptr = mmap64(suggestedPtr, byteCount, prot, flags, fd, offset);
   1810     if (ptr == MAP_FAILED) {
   1811         throwErrnoException(env, "mmap");
   1812     }
   1813     return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
   1814 }
   1815 
   1816 static void Linux_msync(JNIEnv* env, jobject, jlong address, jlong byteCount, jint flags) {
   1817     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
   1818     throwIfMinusOne(env, "msync", TEMP_FAILURE_RETRY(msync(ptr, byteCount, flags)));
   1819 }
   1820 
   1821 static void Linux_munlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
   1822     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
   1823     throwIfMinusOne(env, "munlock", TEMP_FAILURE_RETRY(munlock(ptr, byteCount)));
   1824 }
   1825 
   1826 static void Linux_munmap(JNIEnv* env, jobject, jlong address, jlong byteCount) {
   1827     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
   1828     throwIfMinusOne(env, "munmap", TEMP_FAILURE_RETRY(munmap(ptr, byteCount)));
   1829 }
   1830 
   1831 static jobject Linux_open(JNIEnv* env, jobject, jstring javaPath, jint flags, jint mode) {
   1832     ScopedUtfChars path(env, javaPath);
   1833     if (path.c_str() == NULL) {
   1834         return NULL;
   1835     }
   1836     int fd = throwIfMinusOne(env, "open", TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode)));
   1837     return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
   1838 }
   1839 
   1840 static jobjectArray Linux_pipe2(JNIEnv* env, jobject, jint flags __unused) {
   1841     int fds[2];
   1842     int pipe2_result = throwIfMinusOne(env, "pipe2", TEMP_FAILURE_RETRY(pipe2(&fds[0], flags)));
   1843     if (pipe2_result == -1) {
   1844         return NULL;
   1845     }
   1846     jobjectArray result = env->NewObjectArray(2, JniConstants::fileDescriptorClass, NULL);
   1847     if (result == NULL) {
   1848         return NULL;
   1849     }
   1850     for (int i = 0; i < 2; ++i) {
   1851         ScopedLocalRef<jobject> fd(env, jniCreateFileDescriptor(env, fds[i]));
   1852         if (fd.get() == NULL) {
   1853             return NULL;
   1854         }
   1855         env->SetObjectArrayElement(result, i, fd.get());
   1856         if (env->ExceptionCheck()) {
   1857             return NULL;
   1858         }
   1859     }
   1860     return result;
   1861 }
   1862 
   1863 static jint Linux_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) {
   1864     static jfieldID fdFid = env->GetFieldID(JniConstants::structPollfdClass, "fd", "Ljava/io/FileDescriptor;");
   1865     static jfieldID eventsFid = env->GetFieldID(JniConstants::structPollfdClass, "events", "S");
   1866     static jfieldID reventsFid = env->GetFieldID(JniConstants::structPollfdClass, "revents", "S");
   1867 
   1868     // Turn the Java android.system.StructPollfd[] into a C++ struct pollfd[].
   1869     size_t arrayLength = env->GetArrayLength(javaStructs);
   1870     std::unique_ptr<struct pollfd[]> fds(new struct pollfd[arrayLength]);
   1871     memset(fds.get(), 0, sizeof(struct pollfd) * arrayLength);
   1872     size_t count = 0; // Some trailing array elements may be irrelevant. (See below.)
   1873     for (size_t i = 0; i < arrayLength; ++i) {
   1874         ScopedLocalRef<jobject> javaStruct(env, env->GetObjectArrayElement(javaStructs, i));
   1875         if (javaStruct.get() == NULL) {
   1876             break; // We allow trailing nulls in the array for caller convenience.
   1877         }
   1878         ScopedLocalRef<jobject> javaFd(env, env->GetObjectField(javaStruct.get(), fdFid));
   1879         if (javaFd.get() == NULL) {
   1880             break; // We also allow callers to just clear the fd field (this is what Selector does).
   1881         }
   1882         fds[count].fd = jniGetFDFromFileDescriptor(env, javaFd.get());
   1883         fds[count].events = env->GetShortField(javaStruct.get(), eventsFid);
   1884         ++count;
   1885     }
   1886 
   1887     std::vector<AsynchronousCloseMonitor*> monitors;
   1888     for (size_t i = 0; i < count; ++i) {
   1889         monitors.push_back(new AsynchronousCloseMonitor(fds[i].fd));
   1890     }
   1891 
   1892     int rc;
   1893     while (true) {
   1894         timespec before;
   1895         clock_gettime(CLOCK_MONOTONIC, &before);
   1896 
   1897         rc = poll(fds.get(), count, timeoutMs);
   1898         if (rc >= 0 || errno != EINTR) {
   1899             break;
   1900         }
   1901 
   1902         // We got EINTR. Work out how much of the original timeout is still left.
   1903         if (timeoutMs > 0) {
   1904             timespec now;
   1905             clock_gettime(CLOCK_MONOTONIC, &now);
   1906 
   1907             timespec diff;
   1908             diff.tv_sec = now.tv_sec - before.tv_sec;
   1909             diff.tv_nsec = now.tv_nsec - before.tv_nsec;
   1910             if (diff.tv_nsec < 0) {
   1911                 --diff.tv_sec;
   1912                 diff.tv_nsec += 1000000000;
   1913             }
   1914 
   1915             jint diffMs = diff.tv_sec * 1000 + diff.tv_nsec / 1000000;
   1916             if (diffMs >= timeoutMs) {
   1917                 rc = 0; // We have less than 1ms left anyway, so just time out.
   1918                 break;
   1919             }
   1920 
   1921             timeoutMs -= diffMs;
   1922         }
   1923     }
   1924 
   1925     for (size_t i = 0; i < monitors.size(); ++i) {
   1926         delete monitors[i];
   1927     }
   1928     if (rc == -1) {
   1929         throwErrnoException(env, "poll");
   1930         return -1;
   1931     }
   1932 
   1933     // Update the revents fields in the Java android.system.StructPollfd[].
   1934     for (size_t i = 0; i < count; ++i) {
   1935         ScopedLocalRef<jobject> javaStruct(env, env->GetObjectArrayElement(javaStructs, i));
   1936         if (javaStruct.get() == NULL) {
   1937             return -1;
   1938         }
   1939         env->SetShortField(javaStruct.get(), reventsFid, fds[i].revents);
   1940     }
   1941     return rc;
   1942 }
   1943 
   1944 static void Linux_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
   1945                                   jlong offset __unused, jlong length __unused) {
   1946     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   1947     while ((errno = posix_fallocate64(fd, offset, length)) == EINTR) {
   1948     }
   1949     if (errno != 0) {
   1950         throwErrnoException(env, "posix_fallocate");
   1951     }
   1952 }
   1953 
   1954 static jint Linux_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
   1955                         jlong arg3 __unused, jlong arg4 __unused, jlong arg5 __unused) {
   1956     int result = TEMP_FAILURE_RETRY(prctl(static_cast<int>(option),
   1957                                           static_cast<unsigned long>(arg2),
   1958                                           static_cast<unsigned long>(arg3),
   1959                                           static_cast<unsigned long>(arg4),
   1960                                           static_cast<unsigned long>(arg5)));
   1961     return throwIfMinusOne(env, "prctl", result);
   1962 }
   1963 
   1964 static jint Linux_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
   1965     ScopedBytesRW bytes(env, javaBytes);
   1966     if (bytes.get() == NULL) {
   1967         return -1;
   1968     }
   1969     return IO_FAILURE_RETRY(env, ssize_t, pread64, javaFd, bytes.get() + byteOffset, byteCount, offset);
   1970 }
   1971 
   1972 static jint Linux_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) {
   1973     ScopedBytesRO bytes(env, javaBytes);
   1974     if (bytes.get() == NULL) {
   1975         return -1;
   1976     }
   1977     return IO_FAILURE_RETRY(env, ssize_t, pwrite64, javaFd, bytes.get() + byteOffset, byteCount, offset);
   1978 }
   1979 
   1980 static jint Linux_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
   1981     ScopedBytesRW bytes(env, javaBytes);
   1982     if (bytes.get() == NULL) {
   1983         return -1;
   1984     }
   1985     return IO_FAILURE_RETRY(env, ssize_t, read, javaFd, bytes.get() + byteOffset, byteCount);
   1986 }
   1987 
   1988 static jstring Linux_readlink(JNIEnv* env, jobject, jstring javaPath) {
   1989     ScopedUtfChars path(env, javaPath);
   1990     if (path.c_str() == NULL) {
   1991         return NULL;
   1992     }
   1993 
   1994     std::string result;
   1995     if (!android::base::Readlink(path.c_str(), &result)) {
   1996         throwErrnoException(env, "readlink");
   1997         return NULL;
   1998     }
   1999     return env->NewStringUTF(result.c_str());
   2000 }
   2001 
   2002 static jstring Linux_realpath(JNIEnv* env, jobject, jstring javaPath) {
   2003     ScopedUtfChars path(env, javaPath);
   2004     if (path.c_str() == NULL) {
   2005         return NULL;
   2006     }
   2007 
   2008     std::unique_ptr<char, c_deleter> real_path(realpath(path.c_str(), nullptr));
   2009     if (real_path.get() == nullptr) {
   2010         throwErrnoException(env, "realpath");
   2011         return NULL;
   2012     }
   2013 
   2014     return env->NewStringUTF(real_path.get());
   2015 }
   2016 
   2017 static jint Linux_readv(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
   2018     IoVec<ScopedBytesRW> ioVec(env, env->GetArrayLength(buffers));
   2019     if (!ioVec.init(buffers, offsets, byteCounts)) {
   2020         return -1;
   2021     }
   2022     return IO_FAILURE_RETRY(env, ssize_t, readv, javaFd, ioVec.get(), ioVec.size());
   2023 }
   2024 
   2025 static jint Linux_recvfromBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetSocketAddress) {
   2026     ScopedBytesRW bytes(env, javaBytes);
   2027     if (bytes.get() == NULL) {
   2028         return -1;
   2029     }
   2030     sockaddr_storage ss;
   2031     socklen_t sl = sizeof(ss);
   2032     memset(&ss, 0, sizeof(ss));
   2033     sockaddr* from = (javaInetSocketAddress != NULL) ? reinterpret_cast<sockaddr*>(&ss) : NULL;
   2034     socklen_t* fromLength = (javaInetSocketAddress != NULL) ? &sl : 0;
   2035     jint recvCount = NET_FAILURE_RETRY(env, ssize_t, recvfrom, javaFd, bytes.get() + byteOffset, byteCount, flags, from, fromLength);
   2036     if (recvCount >= 0) {
   2037         // The socket may have performed orderly shutdown and recvCount would return 0 (see man 2
   2038         // recvfrom), in which case ss.ss_family == AF_UNIX and fillInetSocketAddress would fail.
   2039         // Don't fill in the address if recvfrom didn't succeed. http://b/33483694
   2040         if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
   2041             fillInetSocketAddress(env, javaInetSocketAddress, ss);
   2042         }
   2043     }
   2044     return recvCount;
   2045 }
   2046 
   2047 static void Linux_remove(JNIEnv* env, jobject, jstring javaPath) {
   2048     ScopedUtfChars path(env, javaPath);
   2049     if (path.c_str() == NULL) {
   2050         return;
   2051     }
   2052     throwIfMinusOne(env, "remove", TEMP_FAILURE_RETRY(remove(path.c_str())));
   2053 }
   2054 
   2055 static void Linux_removexattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName) {
   2056     ScopedUtfChars path(env, javaPath);
   2057     if (path.c_str() == NULL) {
   2058         return;
   2059     }
   2060     ScopedUtfChars name(env, javaName);
   2061     if (name.c_str() == NULL) {
   2062         return;
   2063     }
   2064 
   2065     int res = removexattr(path.c_str(), name.c_str());
   2066     if (res < 0) {
   2067         throwErrnoException(env, "removexattr");
   2068     }
   2069 }
   2070 
   2071 static void Linux_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
   2072     ScopedUtfChars oldPath(env, javaOldPath);
   2073     if (oldPath.c_str() == NULL) {
   2074         return;
   2075     }
   2076     ScopedUtfChars newPath(env, javaNewPath);
   2077     if (newPath.c_str() == NULL) {
   2078         return;
   2079     }
   2080     throwIfMinusOne(env, "rename", TEMP_FAILURE_RETRY(rename(oldPath.c_str(), newPath.c_str())));
   2081 }
   2082 
   2083 static jlong Linux_sendfile(JNIEnv* env, jobject, jobject javaOutFd, jobject javaInFd, jobject javaOffset, jlong byteCount) {
   2084     int outFd = jniGetFDFromFileDescriptor(env, javaOutFd);
   2085     int inFd = jniGetFDFromFileDescriptor(env, javaInFd);
   2086     off_t offset = 0;
   2087     off_t* offsetPtr = NULL;
   2088     if (javaOffset != NULL) {
   2089         // TODO: fix bionic so we can have a 64-bit off_t!
   2090         offset = env->GetLongField(javaOffset, int64RefValueFid);
   2091         offsetPtr = &offset;
   2092     }
   2093     jlong result = throwIfMinusOne(env, "sendfile", TEMP_FAILURE_RETRY(sendfile(outFd, inFd, offsetPtr, byteCount)));
   2094     if (result == -1) {
   2095         return -1;
   2096     }
   2097     if (javaOffset != NULL) {
   2098         env->SetLongField(javaOffset, int64RefValueFid, offset);
   2099     }
   2100     return result;
   2101 }
   2102 
   2103 static jint Linux_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) {
   2104     ScopedBytesRO bytes(env, javaBytes);
   2105     if (bytes.get() == NULL) {
   2106         return -1;
   2107     }
   2108 
   2109     return NET_IPV4_FALLBACK(env, ssize_t, sendto, javaFd, javaInetAddress, port,
   2110                              NULL_ADDR_OK, bytes.get() + byteOffset, byteCount, flags);
   2111 }
   2112 
   2113 static jint Linux_sendtoBytesSocketAddress(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaSocketAddress) {
   2114     if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
   2115         // Use the InetAddress version so we get the benefit of NET_IPV4_FALLBACK.
   2116         jobject javaInetAddress;
   2117         jint port;
   2118         javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port);
   2119         return Linux_sendtoBytes(env, NULL, javaFd, javaBytes, byteOffset, byteCount, flags,
   2120                                  javaInetAddress, port);
   2121     }
   2122 
   2123     ScopedBytesRO bytes(env, javaBytes);
   2124     if (bytes.get() == NULL) {
   2125         return -1;
   2126     }
   2127 
   2128     sockaddr_storage ss;
   2129     socklen_t sa_len;
   2130     if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
   2131         return -1;
   2132     }
   2133 
   2134     const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss);
   2135     // We don't need the return value because we'll already have thrown.
   2136     return NET_FAILURE_RETRY(env, ssize_t, sendto, javaFd, bytes.get() + byteOffset, byteCount, flags, sa, sa_len);
   2137 }
   2138 
   2139 static void Linux_setegid(JNIEnv* env, jobject, jint egid) {
   2140     throwIfMinusOne(env, "setegid", TEMP_FAILURE_RETRY(setegid(egid)));
   2141 }
   2142 
   2143 static void Linux_setenv(JNIEnv* env, jobject, jstring javaName, jstring javaValue, jboolean overwrite) {
   2144     ScopedUtfChars name(env, javaName);
   2145     if (name.c_str() == NULL) {
   2146         return;
   2147     }
   2148     ScopedUtfChars value(env, javaValue);
   2149     if (value.c_str() == NULL) {
   2150         return;
   2151     }
   2152     throwIfMinusOne(env, "setenv", setenv(name.c_str(), value.c_str(), overwrite));
   2153 }
   2154 
   2155 static void Linux_seteuid(JNIEnv* env, jobject, jint euid) {
   2156     throwIfMinusOne(env, "seteuid", TEMP_FAILURE_RETRY(seteuid(euid)));
   2157 }
   2158 
   2159 static void Linux_setgid(JNIEnv* env, jobject, jint gid) {
   2160     throwIfMinusOne(env, "setgid", TEMP_FAILURE_RETRY(setgid(gid)));
   2161 }
   2162 
   2163 static void Linux_setpgid(JNIEnv* env, jobject, jint pid, int pgid) {
   2164     throwIfMinusOne(env, "setpgid", TEMP_FAILURE_RETRY(setpgid(pid, pgid)));
   2165 }
   2166 
   2167 static void Linux_setregid(JNIEnv* env, jobject, jint rgid, int egid) {
   2168     throwIfMinusOne(env, "setregid", TEMP_FAILURE_RETRY(setregid(rgid, egid)));
   2169 }
   2170 
   2171 static void Linux_setreuid(JNIEnv* env, jobject, jint ruid, int euid) {
   2172     throwIfMinusOne(env, "setreuid", TEMP_FAILURE_RETRY(setreuid(ruid, euid)));
   2173 }
   2174 
   2175 static jint Linux_setsid(JNIEnv* env, jobject) {
   2176     return throwIfMinusOne(env, "setsid", TEMP_FAILURE_RETRY(setsid()));
   2177 }
   2178 
   2179 static void Linux_setsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
   2180     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2181     u_char byte = value;
   2182     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &byte, sizeof(byte))));
   2183 }
   2184 
   2185 static void Linux_setsockoptIfreq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jstring javaInterfaceName) {
   2186     struct ifreq req;
   2187     if (!fillIfreq(env, javaInterfaceName, req)) {
   2188         return;
   2189     }
   2190     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2191     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
   2192 }
   2193 
   2194 static void Linux_setsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
   2195     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2196     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
   2197 }
   2198 
   2199 static void Linux_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
   2200     ip_mreqn req;
   2201     memset(&req, 0, sizeof(req));
   2202     req.imr_ifindex = value;
   2203     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2204     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
   2205 }
   2206 
   2207 static void Linux_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupReq) {
   2208     struct group_req req;
   2209     memset(&req, 0, sizeof(req));
   2210 
   2211     static jfieldID grInterfaceFid = env->GetFieldID(JniConstants::structGroupReqClass, "gr_interface", "I");
   2212     req.gr_interface = env->GetIntField(javaGroupReq, grInterfaceFid);
   2213     // Get the IPv4 or IPv6 multicast address to join or leave.
   2214     static jfieldID grGroupFid = env->GetFieldID(JniConstants::structGroupReqClass, "gr_group", "Ljava/net/InetAddress;");
   2215     ScopedLocalRef<jobject> javaGroup(env, env->GetObjectField(javaGroupReq, grGroupFid));
   2216     socklen_t sa_len;
   2217     if (!inetAddressToSockaddrVerbatim(env, javaGroup.get(), 0, req.gr_group, sa_len)) {
   2218         return;
   2219     }
   2220 
   2221     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2222     int rc = TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req)));
   2223     if (rc == -1 && errno == EINVAL) {
   2224         // Maybe we're a 32-bit binary talking to a 64-bit kernel?
   2225         // glibc doesn't automatically handle this.
   2226         // http://sourceware.org/bugzilla/show_bug.cgi?id=12080
   2227         struct group_req64 {
   2228             uint32_t gr_interface;
   2229             uint32_t my_padding;
   2230             sockaddr_storage gr_group;
   2231         };
   2232         group_req64 req64;
   2233         req64.gr_interface = req.gr_interface;
   2234         memcpy(&req64.gr_group, &req.gr_group, sizeof(req.gr_group));
   2235         rc = TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req64, sizeof(req64)));
   2236     }
   2237     throwIfMinusOne(env, "setsockopt", rc);
   2238 }
   2239 
   2240 static void Linux_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
   2241     static jfieldID lOnoffFid = env->GetFieldID(JniConstants::structLingerClass, "l_onoff", "I");
   2242     static jfieldID lLingerFid = env->GetFieldID(JniConstants::structLingerClass, "l_linger", "I");
   2243     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2244     struct linger value;
   2245     value.l_onoff = env->GetIntField(javaLinger, lOnoffFid);
   2246     value.l_linger = env->GetIntField(javaLinger, lLingerFid);
   2247     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
   2248 }
   2249 
   2250 static void Linux_setsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaTimeval) {
   2251     static jfieldID tvSecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_sec", "J");
   2252     static jfieldID tvUsecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_usec", "J");
   2253     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2254     struct timeval value;
   2255     value.tv_sec = env->GetLongField(javaTimeval, tvSecFid);
   2256     value.tv_usec = env->GetLongField(javaTimeval, tvUsecFid);
   2257     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
   2258 }
   2259 
   2260 static void Linux_setuid(JNIEnv* env, jobject, jint uid) {
   2261     throwIfMinusOne(env, "setuid", TEMP_FAILURE_RETRY(setuid(uid)));
   2262 }
   2263 
   2264 static void Linux_setxattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName,
   2265         jbyteArray javaValue, jint flags) {
   2266     ScopedUtfChars path(env, javaPath);
   2267     if (path.c_str() == NULL) {
   2268         return;
   2269     }
   2270     ScopedUtfChars name(env, javaName);
   2271     if (name.c_str() == NULL) {
   2272         return;
   2273     }
   2274     ScopedBytesRO value(env, javaValue);
   2275     if (value.get() == NULL) {
   2276         return;
   2277     }
   2278     size_t valueLength = env->GetArrayLength(javaValue);
   2279     int res = setxattr(path.c_str(), name.c_str(), value.get(), valueLength, flags);
   2280     if (res < 0) {
   2281         throwErrnoException(env, "setxattr");
   2282     }
   2283 }
   2284 
   2285 static void Linux_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) {
   2286     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2287     throwIfMinusOne(env, "shutdown", TEMP_FAILURE_RETRY(shutdown(fd, how)));
   2288 }
   2289 
   2290 static jobject Linux_socket(JNIEnv* env, jobject, jint domain, jint type, jint protocol) {
   2291     if (domain == AF_PACKET) {
   2292         protocol = htons(protocol);  // Packet sockets specify the protocol in host byte order.
   2293     }
   2294     int fd = throwIfMinusOne(env, "socket", TEMP_FAILURE_RETRY(socket(domain, type, protocol)));
   2295     return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
   2296 }
   2297 
   2298 static void Linux_socketpair(JNIEnv* env, jobject, jint domain, jint type, jint protocol, jobject javaFd1, jobject javaFd2) {
   2299     int fds[2];
   2300     int rc = throwIfMinusOne(env, "socketpair", TEMP_FAILURE_RETRY(socketpair(domain, type, protocol, fds)));
   2301     if (rc != -1) {
   2302         jniSetFileDescriptorOfFD(env, javaFd1, fds[0]);
   2303         jniSetFileDescriptorOfFD(env, javaFd2, fds[1]);
   2304     }
   2305 }
   2306 
   2307 static jlong Linux_splice(JNIEnv* env, jobject, jobject javaFdIn, jobject javaOffIn, jobject javaFdOut, jobject javaOffOut, jlong len, jint flags) {
   2308     int fdIn = jniGetFDFromFileDescriptor(env, javaFdIn);
   2309     int fdOut = jniGetFDFromFileDescriptor(env, javaFdOut);
   2310     int spliceErrno;
   2311 
   2312     jlong offIn = (javaOffIn == NULL ? 0 : env->GetLongField(javaOffIn, int64RefValueFid));
   2313     jlong offOut = (javaOffOut == NULL ? 0 : env->GetLongField(javaOffOut, int64RefValueFid));
   2314     jlong ret = -1;
   2315     do {
   2316         bool wasSignaled = false;
   2317         {
   2318             AsynchronousCloseMonitor monitorIn(fdIn);
   2319             AsynchronousCloseMonitor monitorOut(fdOut);
   2320             ret = splice(fdIn, (javaOffIn == NULL ? NULL : &offIn),
   2321                    fdOut, (javaOffOut == NULL ? NULL : &offOut),
   2322                    len, flags);
   2323             spliceErrno = errno;
   2324             wasSignaled = monitorIn.wasSignaled() || monitorOut.wasSignaled();
   2325         }
   2326         if (wasSignaled) {
   2327             jniThrowException(env, "java/io/InterruptedIOException", "splice interrupted");
   2328             ret = -1;
   2329             break;
   2330         }
   2331         if (ret == -1 && spliceErrno != EINTR) {
   2332             throwErrnoException(env, "splice");
   2333             break;
   2334         }
   2335     } while (ret == -1);
   2336     if (ret == -1) {
   2337         /* If the syscall failed, re-set errno: throwing an exception might have modified it. */
   2338         errno = spliceErrno;
   2339     } else {
   2340         if (javaOffIn != NULL) {
   2341             env->SetLongField(javaOffIn, int64RefValueFid, offIn);
   2342         }
   2343         if (javaOffOut != NULL) {
   2344             env->SetLongField(javaOffOut, int64RefValueFid, offOut);
   2345         }
   2346     }
   2347     return ret;
   2348 }
   2349 
   2350 
   2351 static jobject Linux_stat(JNIEnv* env, jobject, jstring javaPath) {
   2352     return doStat(env, javaPath, false);
   2353 }
   2354 
   2355 static jobject Linux_statvfs(JNIEnv* env, jobject, jstring javaPath) {
   2356     ScopedUtfChars path(env, javaPath);
   2357     if (path.c_str() == NULL) {
   2358         return NULL;
   2359     }
   2360     struct statvfs sb;
   2361     int rc = TEMP_FAILURE_RETRY(statvfs(path.c_str(), &sb));
   2362     if (rc == -1) {
   2363         throwErrnoException(env, "statvfs");
   2364         return NULL;
   2365     }
   2366     return makeStructStatVfs(env, sb);
   2367 }
   2368 
   2369 static jstring Linux_strerror(JNIEnv* env, jobject, jint errnum) {
   2370     char buffer[BUFSIZ];
   2371     const char* message = jniStrError(errnum, buffer, sizeof(buffer));
   2372     return env->NewStringUTF(message);
   2373 }
   2374 
   2375 static jstring Linux_strsignal(JNIEnv* env, jobject, jint signal) {
   2376     return env->NewStringUTF(strsignal(signal));
   2377 }
   2378 
   2379 static void Linux_symlink(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
   2380     ScopedUtfChars oldPath(env, javaOldPath);
   2381     if (oldPath.c_str() == NULL) {
   2382         return;
   2383     }
   2384     ScopedUtfChars newPath(env, javaNewPath);
   2385     if (newPath.c_str() == NULL) {
   2386         return;
   2387     }
   2388     throwIfMinusOne(env, "symlink", TEMP_FAILURE_RETRY(symlink(oldPath.c_str(), newPath.c_str())));
   2389 }
   2390 
   2391 static jlong Linux_sysconf(JNIEnv* env, jobject, jint name) {
   2392     // Since -1 is a valid result from sysconf(3), detecting failure is a little more awkward.
   2393     errno = 0;
   2394     long result = sysconf(name);
   2395     if (result == -1L && errno == EINVAL) {
   2396         throwErrnoException(env, "sysconf");
   2397     }
   2398     return result;
   2399 }
   2400 
   2401 static void Linux_tcdrain(JNIEnv* env, jobject, jobject javaFd) {
   2402     int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2403     throwIfMinusOne(env, "tcdrain", TEMP_FAILURE_RETRY(tcdrain(fd)));
   2404 }
   2405 
   2406 static void Linux_tcsendbreak(JNIEnv* env, jobject, jobject javaFd, jint duration) {
   2407   int fd = jniGetFDFromFileDescriptor(env, javaFd);
   2408   throwIfMinusOne(env, "tcsendbreak", TEMP_FAILURE_RETRY(tcsendbreak(fd, duration)));
   2409 }
   2410 
   2411 static jint Linux_umaskImpl(JNIEnv*, jobject, jint mask) {
   2412     return umask(mask);
   2413 }
   2414 
   2415 static jobject Linux_uname(JNIEnv* env, jobject) {
   2416     struct utsname buf;
   2417     if (TEMP_FAILURE_RETRY(uname(&buf)) == -1) {
   2418         return NULL; // Can't happen.
   2419     }
   2420     return makeStructUtsname(env, buf);
   2421 }
   2422 
   2423 static void Linux_unlink(JNIEnv* env, jobject, jstring javaPathname) {
   2424     ScopedUtfChars pathname(env, javaPathname);
   2425     if (pathname.c_str() == NULL) {
   2426         return;
   2427     }
   2428     throwIfMinusOne(env, "unlink", unlink(pathname.c_str()));
   2429 }
   2430 
   2431 static void Linux_unsetenv(JNIEnv* env, jobject, jstring javaName) {
   2432     ScopedUtfChars name(env, javaName);
   2433     if (name.c_str() == NULL) {
   2434         return;
   2435     }
   2436     throwIfMinusOne(env, "unsetenv", unsetenv(name.c_str()));
   2437 }
   2438 
   2439 static jint Linux_waitpid(JNIEnv* env, jobject, jint pid, jobject javaStatus, jint options) {
   2440     int status;
   2441     int rc = throwIfMinusOne(env, "waitpid", TEMP_FAILURE_RETRY(waitpid(pid, &status, options)));
   2442     if (javaStatus != NULL && rc != -1) {
   2443         env->SetIntField(javaStatus, int32RefValueFid, status);
   2444     }
   2445     return rc;
   2446 }
   2447 
   2448 static jint Linux_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) {
   2449     ScopedBytesRO bytes(env, javaBytes);
   2450     if (bytes.get() == NULL) {
   2451         return -1;
   2452     }
   2453     return IO_FAILURE_RETRY(env, ssize_t, write, javaFd, bytes.get() + byteOffset, byteCount);
   2454 }
   2455 
   2456 static jint Linux_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
   2457     IoVec<ScopedBytesRO> ioVec(env, env->GetArrayLength(buffers));
   2458     if (!ioVec.init(buffers, offsets, byteCounts)) {
   2459         return -1;
   2460     }
   2461     return IO_FAILURE_RETRY(env, ssize_t, writev, javaFd, ioVec.get(), ioVec.size());
   2462 }
   2463 
   2464 #define NATIVE_METHOD_OVERLOAD(className, functionName, signature, variant) \
   2465     { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName ## variant) }
   2466 
   2467 static JNINativeMethod gMethods[] = {
   2468     NATIVE_METHOD(Linux, accept, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)Ljava/io/FileDescriptor;"),
   2469     NATIVE_METHOD(Linux, access, "(Ljava/lang/String;I)Z"),
   2470     NATIVE_METHOD(Linux, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
   2471     NATIVE_METHOD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
   2472     NATIVE_METHOD_OVERLOAD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
   2473     NATIVE_METHOD(Linux, capget,
   2474                   "(Landroid/system/StructCapUserHeader;)[Landroid/system/StructCapUserData;"),
   2475     NATIVE_METHOD(Linux, capset,
   2476                   "(Landroid/system/StructCapUserHeader;[Landroid/system/StructCapUserData;)V"),
   2477     NATIVE_METHOD(Linux, chmod, "(Ljava/lang/String;I)V"),
   2478     NATIVE_METHOD(Linux, chown, "(Ljava/lang/String;II)V"),
   2479     NATIVE_METHOD(Linux, close, "(Ljava/io/FileDescriptor;)V"),
   2480     NATIVE_METHOD(Linux, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
   2481     NATIVE_METHOD_OVERLOAD(Linux, connect, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
   2482     NATIVE_METHOD(Linux, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"),
   2483     NATIVE_METHOD(Linux, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"),
   2484     NATIVE_METHOD(Linux, environ, "()[Ljava/lang/String;"),
   2485     NATIVE_METHOD(Linux, execv, "(Ljava/lang/String;[Ljava/lang/String;)V"),
   2486     NATIVE_METHOD(Linux, execve, "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V"),
   2487     NATIVE_METHOD(Linux, fchmod, "(Ljava/io/FileDescriptor;I)V"),
   2488     NATIVE_METHOD(Linux, fchown, "(Ljava/io/FileDescriptor;II)V"),
   2489     NATIVE_METHOD(Linux, fcntlFlock, "(Ljava/io/FileDescriptor;ILandroid/system/StructFlock;)I"),
   2490     NATIVE_METHOD(Linux, fcntlInt, "(Ljava/io/FileDescriptor;II)I"),
   2491     NATIVE_METHOD(Linux, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"),
   2492     NATIVE_METHOD(Linux, fdatasync, "(Ljava/io/FileDescriptor;)V"),
   2493     NATIVE_METHOD(Linux, fstat, "(Ljava/io/FileDescriptor;)Landroid/system/StructStat;"),
   2494     NATIVE_METHOD(Linux, fstatvfs, "(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;"),
   2495     NATIVE_METHOD(Linux, fsync, "(Ljava/io/FileDescriptor;)V"),
   2496     NATIVE_METHOD(Linux, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
   2497     NATIVE_METHOD(Linux, gai_strerror, "(I)Ljava/lang/String;"),
   2498     NATIVE_METHOD(Linux, getegid, "()I"),
   2499     NATIVE_METHOD(Linux, geteuid, "()I"),
   2500     NATIVE_METHOD(Linux, getgid, "()I"),
   2501     NATIVE_METHOD(Linux, getenv, "(Ljava/lang/String;)Ljava/lang/String;"),
   2502     NATIVE_METHOD(Linux, getnameinfo, "(Ljava/net/InetAddress;I)Ljava/lang/String;"),
   2503     NATIVE_METHOD(Linux, getpeername, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
   2504     NATIVE_METHOD(Linux, getpgid, "(I)I"),
   2505     NATIVE_METHOD(Linux, getpid, "()I"),
   2506     NATIVE_METHOD(Linux, getppid, "()I"),
   2507     NATIVE_METHOD(Linux, getpwnam, "(Ljava/lang/String;)Landroid/system/StructPasswd;"),
   2508     NATIVE_METHOD(Linux, getpwuid, "(I)Landroid/system/StructPasswd;"),
   2509     NATIVE_METHOD(Linux, getrlimit, "(I)Landroid/system/StructRlimit;"),
   2510     NATIVE_METHOD(Linux, getsockname, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
   2511     NATIVE_METHOD(Linux, getsockoptByte, "(Ljava/io/FileDescriptor;II)I"),
   2512     NATIVE_METHOD(Linux, getsockoptInAddr, "(Ljava/io/FileDescriptor;II)Ljava/net/InetAddress;"),
   2513     NATIVE_METHOD(Linux, getsockoptInt, "(Ljava/io/FileDescriptor;II)I"),
   2514     NATIVE_METHOD(Linux, getsockoptLinger, "(Ljava/io/FileDescriptor;II)Landroid/system/StructLinger;"),
   2515     NATIVE_METHOD(Linux, getsockoptTimeval, "(Ljava/io/FileDescriptor;II)Landroid/system/StructTimeval;"),
   2516     NATIVE_METHOD(Linux, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"),
   2517     NATIVE_METHOD(Linux, gettid, "()I"),
   2518     NATIVE_METHOD(Linux, getuid, "()I"),
   2519     NATIVE_METHOD(Linux, getxattr, "(Ljava/lang/String;Ljava/lang/String;)[B"),
   2520     NATIVE_METHOD(Linux, getifaddrs, "()[Landroid/system/StructIfaddrs;"),
   2521     NATIVE_METHOD(Linux, if_indextoname, "(I)Ljava/lang/String;"),
   2522     NATIVE_METHOD(Linux, if_nametoindex, "(Ljava/lang/String;)I"),
   2523     NATIVE_METHOD(Linux, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
   2524     NATIVE_METHOD(Linux, ioctlFlags, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
   2525     NATIVE_METHOD(Linux, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
   2526     NATIVE_METHOD(Linux, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/system/Int32Ref;)I"),
   2527     NATIVE_METHOD(Linux, ioctlMTU, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
   2528     NATIVE_METHOD(Linux, isatty, "(Ljava/io/FileDescriptor;)Z"),
   2529     NATIVE_METHOD(Linux, kill, "(II)V"),
   2530     NATIVE_METHOD(Linux, lchown, "(Ljava/lang/String;II)V"),
   2531     NATIVE_METHOD(Linux, link, "(Ljava/lang/String;Ljava/lang/String;)V"),
   2532     NATIVE_METHOD(Linux, listen, "(Ljava/io/FileDescriptor;I)V"),
   2533     NATIVE_METHOD(Linux, listxattr, "(Ljava/lang/String;)[Ljava/lang/String;"),
   2534     NATIVE_METHOD(Linux, lseek, "(Ljava/io/FileDescriptor;JI)J"),
   2535     NATIVE_METHOD(Linux, lstat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
   2536     NATIVE_METHOD(Linux, mincore, "(JJ[B)V"),
   2537     NATIVE_METHOD(Linux, mkdir, "(Ljava/lang/String;I)V"),
   2538     NATIVE_METHOD(Linux, mkfifo, "(Ljava/lang/String;I)V"),
   2539     NATIVE_METHOD(Linux, mlock, "(JJ)V"),
   2540     NATIVE_METHOD(Linux, mmap, "(JJIILjava/io/FileDescriptor;J)J"),
   2541     NATIVE_METHOD(Linux, msync, "(JJI)V"),
   2542     NATIVE_METHOD(Linux, munlock, "(JJ)V"),
   2543     NATIVE_METHOD(Linux, munmap, "(JJ)V"),
   2544     NATIVE_METHOD(Linux, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"),
   2545     NATIVE_METHOD(Linux, pipe2, "(I)[Ljava/io/FileDescriptor;"),
   2546     NATIVE_METHOD(Linux, poll, "([Landroid/system/StructPollfd;I)I"),
   2547     NATIVE_METHOD(Linux, posix_fallocate, "(Ljava/io/FileDescriptor;JJ)V"),
   2548     NATIVE_METHOD(Linux, prctl, "(IJJJJ)I"),
   2549     NATIVE_METHOD(Linux, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
   2550     NATIVE_METHOD(Linux, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
   2551     NATIVE_METHOD(Linux, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
   2552     NATIVE_METHOD(Linux, readlink, "(Ljava/lang/String;)Ljava/lang/String;"),
   2553     NATIVE_METHOD(Linux, realpath, "(Ljava/lang/String;)Ljava/lang/String;"),
   2554     NATIVE_METHOD(Linux, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
   2555     NATIVE_METHOD(Linux, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
   2556     NATIVE_METHOD(Linux, remove, "(Ljava/lang/String;)V"),
   2557     NATIVE_METHOD(Linux, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
   2558     NATIVE_METHOD(Linux, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
   2559     NATIVE_METHOD(Linux, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/system/Int64Ref;J)J"),
   2560     NATIVE_METHOD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
   2561     NATIVE_METHOD_OVERLOAD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress),
   2562     NATIVE_METHOD(Linux, setegid, "(I)V"),
   2563     NATIVE_METHOD(Linux, setenv, "(Ljava/lang/String;Ljava/lang/String;Z)V"),
   2564     NATIVE_METHOD(Linux, seteuid, "(I)V"),
   2565     NATIVE_METHOD(Linux, setgid, "(I)V"),
   2566     NATIVE_METHOD(Linux, setpgid, "(II)V"),
   2567     NATIVE_METHOD(Linux, setregid, "(II)V"),
   2568     NATIVE_METHOD(Linux, setreuid, "(II)V"),
   2569     NATIVE_METHOD(Linux, setsid, "()I"),
   2570     NATIVE_METHOD(Linux, setsockoptByte, "(Ljava/io/FileDescriptor;III)V"),
   2571     NATIVE_METHOD(Linux, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"),
   2572     NATIVE_METHOD(Linux, setsockoptInt, "(Ljava/io/FileDescriptor;III)V"),
   2573     NATIVE_METHOD(Linux, setsockoptIpMreqn, "(Ljava/io/FileDescriptor;III)V"),
   2574     NATIVE_METHOD(Linux, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupReq;)V"),
   2575     NATIVE_METHOD(Linux, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"),
   2576     NATIVE_METHOD(Linux, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"),
   2577     NATIVE_METHOD(Linux, setuid, "(I)V"),
   2578     NATIVE_METHOD(Linux, setxattr, "(Ljava/lang/String;Ljava/lang/String;[BI)V"),
   2579     NATIVE_METHOD(Linux, shutdown, "(Ljava/io/FileDescriptor;I)V"),
   2580     NATIVE_METHOD(Linux, socket, "(III)Ljava/io/FileDescriptor;"),
   2581     NATIVE_METHOD(Linux, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"),
   2582     NATIVE_METHOD(Linux, splice, "(Ljava/io/FileDescriptor;Landroid/system/Int64Ref;Ljava/io/FileDescriptor;Landroid/system/Int64Ref;JI)J"),
   2583     NATIVE_METHOD(Linux, stat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
   2584     NATIVE_METHOD(Linux, statvfs, "(Ljava/lang/String;)Landroid/system/StructStatVfs;"),
   2585     NATIVE_METHOD(Linux, strerror, "(I)Ljava/lang/String;"),
   2586     NATIVE_METHOD(Linux, strsignal, "(I)Ljava/lang/String;"),
   2587     NATIVE_METHOD(Linux, symlink, "(Ljava/lang/String;Ljava/lang/String;)V"),
   2588     NATIVE_METHOD(Linux, sysconf, "(I)J"),
   2589     NATIVE_METHOD(Linux, tcdrain, "(Ljava/io/FileDescriptor;)V"),
   2590     NATIVE_METHOD(Linux, tcsendbreak, "(Ljava/io/FileDescriptor;I)V"),
   2591     NATIVE_METHOD(Linux, umaskImpl, "(I)I"),
   2592     NATIVE_METHOD(Linux, uname, "()Landroid/system/StructUtsname;"),
   2593     NATIVE_METHOD(Linux, unlink, "(Ljava/lang/String;)V"),
   2594     NATIVE_METHOD(Linux, unsetenv, "(Ljava/lang/String;)V"),
   2595     NATIVE_METHOD(Linux, waitpid, "(ILandroid/system/Int32Ref;I)I"),
   2596     NATIVE_METHOD(Linux, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
   2597     NATIVE_METHOD(Linux, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
   2598 };
   2599 void register_libcore_io_Linux(JNIEnv* env) {
   2600     // Note: it is safe to only cache the fields as boot classpath classes are never
   2601     //       unloaded.
   2602     ScopedLocalRef<jclass> int32RefClass(env, env->FindClass("android/system/Int32Ref"));
   2603     CHECK(int32RefClass != nullptr);
   2604     int32RefValueFid = env->GetFieldID(int32RefClass.get(), "value", "I");
   2605     CHECK(int32RefValueFid != nullptr);
   2606 
   2607     ScopedLocalRef<jclass> int64RefClass(env, env->FindClass("android/system/Int64Ref"));
   2608     CHECK(int64RefClass != nullptr);
   2609     int64RefValueFid = env->GetFieldID(int64RefClass.get(), "value", "J");
   2610     CHECK(int64RefValueFid != nullptr);
   2611 
   2612     jniRegisterNativeMethods(env, "libcore/io/Linux", gMethods, NELEM(gMethods));
   2613 }
   2614