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