19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "LocalSocketImpl" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h" 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h" 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/socket.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/un.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <arpa/inet.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netinet/in.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h> 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/sockets.h> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netinet/tcp.h> 38092eb8d43baffd7723bc7847c180a32fb5269481You Kim#include <ScopedUtfChars.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID field_inboundFileDescriptors; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID field_outboundFileDescriptors; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass class_Credentials; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass class_FileDescriptor; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_CredentialsInit; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native void connectLocal(FileDescriptor fd, 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * String name, int namespace) throws IOException 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_connect_local(JNIEnv *env, jobject object, 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject fileDescriptor, jstring name, jint namespaceId) 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64092eb8d43baffd7723bc7847c180a32fb5269481You Kim ScopedUtfChars nameUtf8(env, name); 65092eb8d43baffd7723bc7847c180a32fb5269481You Kim 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = socket_local_client_connect( 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd, 68092eb8d43baffd7723bc7847c180a32fb5269481You Kim nameUtf8.c_str(), 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project namespaceId, 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SOCK_STREAM); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEFAULT_BACKLOG 4 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes/* private native void bindLocal(FileDescriptor fd, String name, namespace) 8169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes * throws IOException; 8269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes */ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_bind_local (JNIEnv *env, jobject object, jobject fileDescriptor, 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring name, jint namespaceId) 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name == NULL) { 9269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 93092eb8d43baffd7723bc7847c180a32fb5269481You Kim return; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 102092eb8d43baffd7723bc7847c180a32fb5269481You Kim ScopedUtfChars nameUtf8(env, name); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 104092eb8d43baffd7723bc7847c180a32fb5269481You Kim ret = socket_local_server_bind(fd, nameUtf8.c_str(), namespaceId); 10569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native void listen_native(int fd, int backlog) throws IOException; */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 114f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhatsocket_listen (JNIEnv *env, jobject object, jobject fileDescriptor, jint backlog) 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = listen(fd, backlog); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native FileDescriptor 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** accept (FileDescriptor fd, LocalSocketImpl s) 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** throws IOException; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_accept (JNIEnv *env, jobject object, jobject fileDescriptor, jobject s) 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project union { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr address; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr_un un_address; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } sa; 14469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int retFD; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t addrlen; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s == NULL) { 15169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addrlen = sizeof(sa); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = accept(fd, &(sa.address), &addrlen); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retFD = ret; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniCreateFileDescriptor(env, retFD); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native void shutdown(FileDescriptor fd, boolean shutdownInput) */ 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_shutdown (JNIEnv *env, jobject object, jobject fileDescriptor, 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean shutdownInput) 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = shutdown(fd, shutdownInput ? SHUT_RD : SHUT_WR); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjava_opt_to_real(int optID, int* opt, int* level) 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (optID) 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4098: 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_RCVBUF; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4097: 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_SNDBUF; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4102: 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_SNDTIMEO; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 128: 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_LINGER; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 1: 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = TCP_NODELAY; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = IPPROTO_TCP; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4: 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_REUSEADDR; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint 234f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhatsocket_getOption(JNIEnv *env, jobject object, jobject fileDescriptor, jint optID) 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret, value; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int opt, level; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t size = sizeof(int); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java_opt_to_real(optID, &opt, &level)) { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, -1); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (opt) 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SO_LINGER: 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct linger lingr; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = sizeof(lingr); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = getsockopt(fd, level, opt, &lingr, &size); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!lingr.l_onoff) { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project value = -1; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project value = lingr.l_linger; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = getsockopt(fd, level, opt, &value, &size); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret != 0) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return value; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void socket_setOption( 282f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat JNIEnv *env, jobject object, jobject fileDescriptor, jint optID, 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint boolValue, jint intValue) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int optname; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int level; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java_opt_to_real(optID, &optname, &level)) { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, -1); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (optname) { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SO_LINGER: { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SO_LINGER is special because it needs to use a special 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "linger" struct as well as use the incoming boolean 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argument specially. 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct linger lingr; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lingr.l_onoff = boolValue ? 1 : 0; // Force it to be 0 or 1. 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lingr.l_linger = intValue; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, level, optname, &lingr, sizeof(lingr)); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SO_SNDTIMEO: { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SO_TIMEOUT from the core library gets converted to 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SO_SNDTIMEO, but the option is supposed to set both 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * send and receive timeouts. Note: The incoming timeout 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * value is in milliseconds. 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timeval timeout; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timeout.tv_sec = intValue / 1000; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timeout.tv_usec = (intValue % 1000) * 1000; 32369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void *)&timeout, sizeof(timeout)); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret == 0) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void *)&timeout, sizeof(timeout)); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In all other cases, the translated option level and 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * optname may be used directly for a call to setsockopt(). 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, level, optname, &intValue, sizeof(intValue)); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret != 0) { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 34971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzystatic jint socket_pending (JNIEnv *env, jobject object, 35071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy jobject fileDescriptor) 35171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy{ 35271bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy int fd; 35371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy 35471bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 35571bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy 35671bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy if (env->ExceptionOccurred() != NULL) { 35771bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy return (jint)-1; 35871bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy } 35971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy 36071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy int pending; 36171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy int ret = ioctl(fd, TIOCOUTQ, &pending); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy // If this were a non-socket fd, there would be other cases to worry 36471bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy // about... 36571bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy 36671bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy //ALOGD("socket_pending, ioctl ret:%d, pending:%d", ret, pending); 36771bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy if (ret < 0) { 36871bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy jniThrowIOException(env, errno); 36971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy return (jint) 0; 37071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy } 37171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy 37271bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy return (jint)pending; 37371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy} 37469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jint socket_available (JNIEnv *env, jobject object, 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject fileDescriptor) 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int avail; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret = ioctl(fd, FIONREAD, &avail); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this were a non-socket fd, there would be other cases to worry 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // about... 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint) 0; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)avail; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// there appears to be a bionic bug that prevents this version from working. 40069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t ret; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct msghdr msg; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = recvmsg(fd, &msg, MSG_PEEK | MSG_DONTWAIT | MSG_NOSIGNAL); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // MSG_PEEK returns 0 on EOF and EWOULDBLOCK on none available 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0 && errno == EWOULDBLOCK) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } if (ret < 0) { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)ret; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 42469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes * Processes ancillary data, handling only 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SCM_RIGHTS. Creates appropriate objects and sets appropriate 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fields in the LocalSocketImpl object. Returns 0 on success 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or -1 if an exception was thrown. 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int socket_process_cmsg(JNIEnv *env, jobject thisJ, struct msghdr * pMsg) 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct cmsghdr *cmsgptr; 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes for (cmsgptr = CMSG_FIRSTHDR(pMsg); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(pMsg, cmsgptr)) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cmsgptr->cmsg_level != SOL_SOCKET) { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cmsgptr->cmsg_type == SCM_RIGHTS) { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int *pDescriptors = (int *)CMSG_DATA(cmsgptr); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobjectArray fdArray; 44369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes int count 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = ((cmsgptr->cmsg_len - CMSG_LEN(0)) / sizeof(int)); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 0) { 44769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowException(env, "java/io/IOException", 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invalid cmsg length"); 449092eb8d43baffd7723bc7847c180a32fb5269481You Kim return -1; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fdArray = env->NewObjectArray(count, class_FileDescriptor, NULL); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fdArray == NULL) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 45969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jobject fdObject 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = jniCreateFileDescriptor(env, pDescriptors[i]); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetObjectArrayElement(fdArray, i, fdObject); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetObjectField(thisJ, field_inboundFileDescriptors, fdArray); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reads data from a socket into buf, processing any ancillary data 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and adding it to thisJ. 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the length of normal data read, or -1 if an exception has 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * been thrown in this function. 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 49169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic ssize_t socket_read_all(JNIEnv *env, jobject thisJ, int fd, 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *buffer, size_t len) 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t ret; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t bytesread = 0; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct msghdr msg; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct iovec iv; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char *buf = (unsigned char *)buffer; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Enough buffer for a pile of fd's. We throw an exception if 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this buffer is too small. 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct cmsghdr cmsgbuf[2*sizeof(cmsghdr) + 0x100]; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&iv, 0, sizeof(iv)); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_base = buf; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_len = len; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iov = &iv; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iovlen = 1; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_control = cmsgbuf; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_controllen = sizeof(cmsgbuf); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = recvmsg(fd, &msg, MSG_NOSIGNAL); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0 && errno == EPIPE) { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Treat this as an end of stream 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // To us, any of the above flags are a fatal error 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowException(env, "java/io/IOException", 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unexpected error or truncation during recvmsg()"); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret >= 0) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socket_process_cmsg(env, thisJ, &msg); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Writes all the data in the specified buffer to the specified socket. 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns 0 on success or -1 if an exception was thrown. 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int socket_write_all(JNIEnv *env, jobject object, int fd, 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *buf, size_t len) 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t ret; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct msghdr msg; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char *buffer = (unsigned char *)buf; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jobjectArray outboundFds 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = (jobjectArray)env->GetObjectField( 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project object, field_outboundFileDescriptors); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct cmsghdr *cmsg; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int countFds = outboundFds == NULL ? 0 : env->GetArrayLength(outboundFds); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fds[countFds]; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char msgbuf[CMSG_SPACE(countFds)]; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Add any pending outbound file descriptors to the message 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outboundFds != NULL) { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < countFds; i++) { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject fdObject = env->GetObjectArrayElement(outboundFds, i); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fds[i] = jniGetFDFromFileDescriptor(env, fdObject); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // See "man cmsg" really 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_control = msgbuf; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_controllen = sizeof msgbuf; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg = CMSG_FIRSTHDR(&msg); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg->cmsg_level = SOL_SOCKET; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg->cmsg_type = SCM_RIGHTS; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg->cmsg_len = CMSG_LEN(sizeof fds); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(CMSG_DATA(cmsg), fds, sizeof fds); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We only write our msg_control during the first write 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct iovec iv; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&iv, 0, sizeof(iv)); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_base = buffer; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_len = len; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iov = &iv; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iovlen = 1; 60969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = sendmsg(fd, &msg, MSG_NOSIGNAL); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buffer += ret; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len -= ret; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wipes out any msg_control too 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint socket_read (JNIEnv *env, jobject object, jobject fileDescriptor) 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 63569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)0; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char buf; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = socket_read_all(env, object, fd, &buf, 1); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)0; 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err == 0) { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // end of file 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)buf; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 66269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jint socket_readba (JNIEnv *env, jobject object, 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray buffer, jint off, jint len, jobject fileDescriptor) 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte* byteBuffer; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL || buffer == NULL) { 67069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) { 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL); 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 0) { 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // because socket_read_all returns 0 on EOF 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuffer = env->GetByteArrayElements(buffer, NULL); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == byteBuffer) { 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // an exception will have been thrown 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 69769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes ret = socket_read_all(env, object, 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd, byteBuffer + off, len); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A return of -1 above means an exception is pending 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(buffer, byteBuffer, 0); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint) ((ret == 0) ? -1 : ret); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 70769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic void socket_write (JNIEnv *env, jobject object, 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint b, jobject fileDescriptor) 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 71469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = socket_write_all(env, object, fd, &b, 1); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A return of -1 above means an exception is pending 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic void socket_writeba (JNIEnv *env, jobject object, 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray buffer, jint off, jint len, jobject fileDescriptor) 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte* byteBuffer; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL || buffer == NULL) { 73769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuffer = env->GetByteArrayElements(buffer,NULL); 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == byteBuffer) { 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // an exception will have been thrown 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes err = socket_write_all(env, object, fd, 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuffer + off, len); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A return of -1 above means an exception is pending 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(buffer, byteBuffer, JNI_ABORT); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 76769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jobject socket_get_peer_credentials(JNIEnv *env, 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject object, jobject fileDescriptor) 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 77469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct ucred creds; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&creds, 0, sizeof(creds)); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t szCreds = sizeof(creds); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes err = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (szCreds == 0) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 80069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes return env->NewObject(class_Credentials, method_CredentialsInit, 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project creds.pid, creds.uid, creds.gid); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//TODO change this to return an instance of LocalSocketAddress 80669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jobject socket_getSockName(JNIEnv *env, 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject object, jobject fileDescriptor) 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 81369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project union { 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr address; 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr_un un_address; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } sa; 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&sa, 0, sizeof(sa)); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t namelen = sizeof(sa); 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = getsockname(fd, &(sa.address), &namelen); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sa.address.sa_family != AF_UNIX) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We think we're an impl only for AF_UNIX, so this should never happen. 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, EINVAL); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sa.un_address.sun_path[0] == '\0') { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"getOption_native", "(Ljava/io/FileDescriptor;I)I", (void*)socket_getOption}, 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"setOption_native", "(Ljava/io/FileDescriptor;III)V", (void*)socket_setOption}, 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"connectLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)socket_connect_local}, 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"bindLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", (void*)socket_bind_local}, 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"listen_native", "(Ljava/io/FileDescriptor;I)V", (void*)socket_listen}, 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept}, 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown}, 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available}, 86971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy {"pending_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_pending}, 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read}, 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba}, 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba}, 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"write_native", "(ILjava/io/FileDescriptor;)V", (void*) socket_write}, 87469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes {"getPeerCredentials_native", 87569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes "(Ljava/io/FileDescriptor;)Landroid/net/Credentials;", 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) socket_get_peer_credentials} 87769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes //,{"getSockName_native", "(Ljava/io/FileDescriptor;)Ljava/lang/String;", 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (void *) socket_getSockName} 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_net_LocalSocketImpl(JNIEnv *env) 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz; 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clazz = env->FindClass("android/net/LocalSocketImpl"); 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (clazz == NULL) { 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 89269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes field_inboundFileDescriptors = env->GetFieldID(clazz, 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "inboundFileDescriptors", "[Ljava/io/FileDescriptor;"); 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (field_inboundFileDescriptors == NULL) { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 89969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes field_outboundFileDescriptors = env->GetFieldID(clazz, 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "outboundFileDescriptors", "[Ljava/io/FileDescriptor;"); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (field_outboundFileDescriptors == NULL) { 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_Credentials = env->FindClass("android/net/Credentials"); 90769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (class_Credentials == NULL) { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_Credentials = (jclass)env->NewGlobalRef(class_Credentials); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_FileDescriptor = env->FindClass("java/io/FileDescriptor"); 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (class_FileDescriptor == NULL) { 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_FileDescriptor = (jclass)env->NewGlobalRef(class_FileDescriptor); 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 92269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes method_CredentialsInit 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = env->GetMethodID(class_Credentials, "<init>", "(III)V"); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (method_CredentialsInit == NULL) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android/net/LocalSocketImpl", gMethods, NELEM(gMethods)); 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecterror: 9333762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Error registering android.net.LocalSocketImpl"); 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 938