android_net_LocalSocketImpl.cpp revision 092eb8d43baffd7723bc7847c180a32fb5269481
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/* 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * private native FileDescriptor 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * create_native(boolean stream) 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * throws IOException; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_create (JNIEnv *env, jobject object, jboolean stream) 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = socket(PF_LOCAL, stream ? SOCK_STREAM : SOCK_DGRAM, 0); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniCreateFileDescriptor(env,ret); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native void connectLocal(FileDescriptor fd, 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * String name, int namespace) throws IOException 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_connect_local(JNIEnv *env, jobject object, 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject fileDescriptor, jstring name, jint namespaceId) 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84092eb8d43baffd7723bc7847c180a32fb5269481You Kim ScopedUtfChars nameUtf8(env, name); 85092eb8d43baffd7723bc7847c180a32fb5269481You Kim 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = socket_local_client_connect( 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd, 88092eb8d43baffd7723bc7847c180a32fb5269481You Kim nameUtf8.c_str(), 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project namespaceId, 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SOCK_STREAM); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEFAULT_BACKLOG 4 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes/* private native void bindLocal(FileDescriptor fd, String name, namespace) 10169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes * throws IOException; 10269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes */ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_bind_local (JNIEnv *env, jobject object, jobject fileDescriptor, 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring name, jint namespaceId) 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name == NULL) { 11269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 113092eb8d43baffd7723bc7847c180a32fb5269481You Kim return; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 122092eb8d43baffd7723bc7847c180a32fb5269481You Kim ScopedUtfChars nameUtf8(env, name); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 124092eb8d43baffd7723bc7847c180a32fb5269481You Kim ret = socket_local_server_bind(fd, nameUtf8.c_str(), namespaceId); 12569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native void listen_native(int fd, int backlog) throws IOException; */ 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_listen (JNIEnv *env, jobject object, jobject fileDescriptor, int backlog) 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = listen(fd, backlog); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native FileDescriptor 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** accept (FileDescriptor fd, LocalSocketImpl s) 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** throws IOException; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_accept (JNIEnv *env, jobject object, jobject fileDescriptor, jobject s) 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project union { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr address; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr_un un_address; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } sa; 16469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int retFD; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t addrlen; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s == NULL) { 17169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addrlen = sizeof(sa); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = accept(fd, &(sa.address), &addrlen); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retFD = ret; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniCreateFileDescriptor(env, retFD); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* private native void shutdown(FileDescriptor fd, boolean shutdownInput) */ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_shutdown (JNIEnv *env, jobject object, jobject fileDescriptor, 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean shutdownInput) 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = shutdown(fd, shutdownInput ? SHUT_RD : SHUT_WR); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjava_opt_to_real(int optID, int* opt, int* level) 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (optID) 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4098: 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_RCVBUF; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4097: 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_SNDBUF; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4102: 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_SNDTIMEO; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 128: 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_LINGER; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 1: 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = TCP_NODELAY; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = IPPROTO_TCP; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 4: 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *opt = SO_REUSEADDR; 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *level = SOL_SOCKET; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsocket_getOption(JNIEnv *env, jobject object, jobject fileDescriptor, int optID) 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret, value; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int opt, level; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t size = sizeof(int); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java_opt_to_real(optID, &opt, &level)) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, -1); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (opt) 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SO_LINGER: 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct linger lingr; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = sizeof(lingr); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = getsockopt(fd, level, opt, &lingr, &size); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!lingr.l_onoff) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project value = -1; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project value = lingr.l_linger; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = getsockopt(fd, level, opt, &value, &size); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret != 0) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return value; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void socket_setOption( 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv *env, jobject object, jobject fileDescriptor, int optID, 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint boolValue, jint intValue) { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int optname; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int level; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java_opt_to_real(optID, &optname, &level)) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, -1); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (optname) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SO_LINGER: { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SO_LINGER is special because it needs to use a special 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "linger" struct as well as use the incoming boolean 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argument specially. 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct linger lingr; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lingr.l_onoff = boolValue ? 1 : 0; // Force it to be 0 or 1. 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lingr.l_linger = intValue; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, level, optname, &lingr, sizeof(lingr)); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SO_SNDTIMEO: { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SO_TIMEOUT from the core library gets converted to 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SO_SNDTIMEO, but the option is supposed to set both 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * send and receive timeouts. Note: The incoming timeout 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * value is in milliseconds. 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timeval timeout; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timeout.tv_sec = intValue / 1000; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timeout.tv_usec = (intValue % 1000) * 1000; 34369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void *)&timeout, sizeof(timeout)); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret == 0) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void *)&timeout, sizeof(timeout)); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In all other cases, the translated option level and 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * optname may be used directly for a call to setsockopt(). 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setsockopt(fd, level, optname, &intValue, sizeof(intValue)); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret != 0) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jint socket_available (JNIEnv *env, jobject object, 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject fileDescriptor) 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 1 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int avail; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret = ioctl(fd, FIONREAD, &avail); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this were a non-socket fd, there would be other cases to worry 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // about... 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint) 0; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)avail; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// there appears to be a bionic bug that prevents this version from working. 39669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t ret; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct msghdr msg; 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = recvmsg(fd, &msg, MSG_PEEK | MSG_DONTWAIT | MSG_NOSIGNAL); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // MSG_PEEK returns 0 on EOF and EWOULDBLOCK on none available 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0 && errno == EWOULDBLOCK) { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } if (ret < 0) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)ret; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void socket_close (JNIEnv *env, jobject object, jobject fileDescriptor) 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 42569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = close(fd); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (err < 0 && errno == EINTR); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 44669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes * Processes ancillary data, handling only 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SCM_RIGHTS. Creates appropriate objects and sets appropriate 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fields in the LocalSocketImpl object. Returns 0 on success 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or -1 if an exception was thrown. 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int socket_process_cmsg(JNIEnv *env, jobject thisJ, struct msghdr * pMsg) 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct cmsghdr *cmsgptr; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes for (cmsgptr = CMSG_FIRSTHDR(pMsg); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(pMsg, cmsgptr)) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cmsgptr->cmsg_level != SOL_SOCKET) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cmsgptr->cmsg_type == SCM_RIGHTS) { 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int *pDescriptors = (int *)CMSG_DATA(cmsgptr); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobjectArray fdArray; 46569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes int count 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = ((cmsgptr->cmsg_len - CMSG_LEN(0)) / sizeof(int)); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 0) { 46969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowException(env, "java/io/IOException", 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invalid cmsg length"); 471092eb8d43baffd7723bc7847c180a32fb5269481You Kim return -1; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fdArray = env->NewObjectArray(count, class_FileDescriptor, NULL); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fdArray == NULL) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 48169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jobject fdObject 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = jniCreateFileDescriptor(env, pDescriptors[i]); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetObjectArrayElement(fdArray, i, fdObject); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetObjectField(thisJ, field_inboundFileDescriptors, fdArray); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reads data from a socket into buf, processing any ancillary data 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and adding it to thisJ. 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the length of normal data read, or -1 if an exception has 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * been thrown in this function. 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 51369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic ssize_t socket_read_all(JNIEnv *env, jobject thisJ, int fd, 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *buffer, size_t len) 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t ret; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t bytesread = 0; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct msghdr msg; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct iovec iv; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char *buf = (unsigned char *)buffer; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Enough buffer for a pile of fd's. We throw an exception if 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this buffer is too small. 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct cmsghdr cmsgbuf[2*sizeof(cmsghdr) + 0x100]; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&iv, 0, sizeof(iv)); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_base = buf; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_len = len; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iov = &iv; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iovlen = 1; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_control = cmsgbuf; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_controllen = sizeof(cmsgbuf); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = recvmsg(fd, &msg, MSG_NOSIGNAL); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0 && errno == EPIPE) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Treat this as an end of stream 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // To us, any of the above flags are a fatal error 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55369a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowException(env, "java/io/IOException", 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unexpected error or truncation during recvmsg()"); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret >= 0) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socket_process_cmsg(env, thisJ, &msg); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Writes all the data in the specified buffer to the specified socket. 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns 0 on success or -1 if an exception was thrown. 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int socket_write_all(JNIEnv *env, jobject object, int fd, 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *buf, size_t len) 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t ret; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct msghdr msg; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char *buffer = (unsigned char *)buf; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jobjectArray outboundFds 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = (jobjectArray)env->GetObjectField( 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project object, field_outboundFileDescriptors); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct cmsghdr *cmsg; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int countFds = outboundFds == NULL ? 0 : env->GetArrayLength(outboundFds); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fds[countFds]; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char msgbuf[CMSG_SPACE(countFds)]; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Add any pending outbound file descriptors to the message 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outboundFds != NULL) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < countFds; i++) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject fdObject = env->GetObjectArrayElement(outboundFds, i); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fds[i] = jniGetFDFromFileDescriptor(env, fdObject); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // See "man cmsg" really 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_control = msgbuf; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_controllen = sizeof msgbuf; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg = CMSG_FIRSTHDR(&msg); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg->cmsg_level = SOL_SOCKET; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg->cmsg_type = SCM_RIGHTS; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmsg->cmsg_len = CMSG_LEN(sizeof fds); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(CMSG_DATA(cmsg), fds, sizeof fds); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We only write our msg_control during the first write 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (len > 0) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct iovec iv; 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&iv, 0, sizeof(iv)); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_base = buffer; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iv.iov_len = len; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iov = &iv; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.msg_iovlen = 1; 63169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = sendmsg(fd, &msg, MSG_NOSIGNAL); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (ret < 0 && errno == EINTR); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buffer += ret; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len -= ret; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wipes out any msg_control too 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&msg, 0, sizeof(msg)); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint socket_read (JNIEnv *env, jobject object, jobject fileDescriptor) 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 65769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)0; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char buf; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = socket_read_all(env, object, fd, &buf, 1); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)0; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err == 0) { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // end of file 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)buf; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jint socket_readba (JNIEnv *env, jobject object, 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray buffer, jint off, jint len, jobject fileDescriptor) 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte* byteBuffer; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL || buffer == NULL) { 69269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 0) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // because socket_read_all returns 0 on EOF 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuffer = env->GetByteArrayElements(buffer, NULL); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == byteBuffer) { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // an exception will have been thrown 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint)-1; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes ret = socket_read_all(env, object, 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd, byteBuffer + off, len); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A return of -1 above means an exception is pending 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(buffer, byteBuffer, 0); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jint) ((ret == 0) ? -1 : ret); 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic void socket_write (JNIEnv *env, jobject object, 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint b, 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 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 73669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = socket_write_all(env, object, fd, &b, 1); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A return of -1 above means an exception is pending 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic void socket_writeba (JNIEnv *env, jobject object, 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray buffer, jint off, jint len, jobject fileDescriptor) 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte* byteBuffer; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL || buffer == NULL) { 75969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) { 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuffer = env->GetByteArrayElements(buffer,NULL); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == byteBuffer) { 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // an exception will have been thrown 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes err = socket_write_all(env, object, fd, 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuffer + off, len); 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A return of -1 above means an exception is pending 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(buffer, byteBuffer, JNI_ABORT); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78969a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jobject socket_get_peer_credentials(JNIEnv *env, 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject object, jobject fileDescriptor) 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 79669a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct ucred creds; 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&creds, 0, sizeof(creds)); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t szCreds = sizeof(creds); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 81169a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes err = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (szCreds == 0) { 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 82269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes return env->NewObject(class_Credentials, method_CredentialsInit, 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project creds.pid, creds.uid, creds.gid); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//TODO change this to return an instance of LocalSocketAddress 82869a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughesstatic jobject socket_getSockName(JNIEnv *env, 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject object, jobject fileDescriptor) 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err; 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd; 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fileDescriptor == NULL) { 83569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes jniThrowNullPointerException(env, NULL); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionOccurred() != NULL) { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project union { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr address; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr_un un_address; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } sa; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&sa, 0, sizeof(sa)); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t namelen = sizeof(sa); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err = getsockname(fd, &(sa.address), &namelen); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err < 0) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sa.address.sa_family != AF_UNIX) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We think we're an impl only for AF_UNIX, so this should never happen. 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, EINVAL); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sa.un_address.sun_path[0] == '\0') { 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"getOption_native", "(Ljava/io/FileDescriptor;I)I", (void*)socket_getOption}, 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"setOption_native", "(Ljava/io/FileDescriptor;III)V", (void*)socket_setOption}, 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"create_native", "(Z)Ljava/io/FileDescriptor;", (void*)socket_create}, 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"connectLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)socket_connect_local}, 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"bindLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", (void*)socket_bind_local}, 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"listen_native", "(Ljava/io/FileDescriptor;I)V", (void*)socket_listen}, 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept}, 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown}, 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available}, 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"close_native", "(Ljava/io/FileDescriptor;)V", (void*) socket_close}, 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read}, 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba}, 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba}, 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"write_native", "(ILjava/io/FileDescriptor;)V", (void*) socket_write}, 89769a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes {"getPeerCredentials_native", 89869a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes "(Ljava/io/FileDescriptor;)Landroid/net/Credentials;", 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) socket_get_peer_credentials} 90069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes //,{"getSockName_native", "(Ljava/io/FileDescriptor;)Ljava/lang/String;", 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (void *) socket_getSockName} 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_net_LocalSocketImpl(JNIEnv *env) 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz; 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clazz = env->FindClass("android/net/LocalSocketImpl"); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (clazz == NULL) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 91569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes field_inboundFileDescriptors = env->GetFieldID(clazz, 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "inboundFileDescriptors", "[Ljava/io/FileDescriptor;"); 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (field_inboundFileDescriptors == NULL) { 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 92269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes field_outboundFileDescriptors = env->GetFieldID(clazz, 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "outboundFileDescriptors", "[Ljava/io/FileDescriptor;"); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (field_outboundFileDescriptors == NULL) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_Credentials = env->FindClass("android/net/Credentials"); 93069a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (class_Credentials == NULL) { 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_Credentials = (jclass)env->NewGlobalRef(class_Credentials); 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_FileDescriptor = env->FindClass("java/io/FileDescriptor"); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (class_FileDescriptor == NULL) { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class_FileDescriptor = (jclass)env->NewGlobalRef(class_FileDescriptor); 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 94569a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes method_CredentialsInit 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = env->GetMethodID(class_Credentials, "<init>", "(III)V"); 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (method_CredentialsInit == NULL) { 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto error; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android/net/LocalSocketImpl", gMethods, NELEM(gMethods)); 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecterror: 9563762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Error registering android.net.LocalSocketImpl"); 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 961