SocketListener.cpp revision 168415b822cae1f8b54ef09c41c11a9b97b87f40
1168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat/* 2168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Copyright (C) 2008 The Android Open Source Project 3168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 4168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * you may not use this file except in compliance with the License. 6168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * You may obtain a copy of the License at 7168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 8168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 10168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Unless required by applicable law or agreed to in writing, software 11168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * See the License for the specific language governing permissions and 14168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * limitations under the License. 15168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat */ 16168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <stdio.h> 17168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <errno.h> 18168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <stdlib.h> 19168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/socket.h> 20168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/select.h> 21168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/time.h> 22168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/types.h> 23168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/un.h> 24168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 25168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#define LOG_TAG "SocketListener" 26168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <cutils/log.h> 27168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 28168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <cutils/sockets.h> 29168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 30168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sysutils/SocketListener.h> 31168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 32168415b822cae1f8b54ef09c41c11a9b97b87f40San MehatSocketListener::SocketListener(const char *socketName, bool acceptClients) { 33168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mAcceptClients = acceptClients; 34168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mCsock = -1; 35168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName = socketName; 36168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSock = -1; 37168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 38168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 39168415b822cae1f8b54ef09c41c11a9b97b87f40San MehatSocketListener::SocketListener(int socketFd, bool acceptClients) { 40168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mAcceptClients = acceptClients; 41168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mCsock = -1; 42168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName = NULL; 43168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSock = socketFd; 44168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 45168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 46168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehatint SocketListener::run() { 47168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 48168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (!mSocketName && mSock == -1) { 49168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat errno = EINVAL; 50168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 51168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if (mSocketName) { 52168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if ((mSock = android_get_control_socket(mSocketName)) < 0) { 53168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat LOGE("Obtaining file descriptor socket '%s' failed: %s", 54168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName, strerror(errno)); 55168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 56168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 57168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 58168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 59168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (mAcceptClients) { 60168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (listen(mSock, 4) < 0) { 61168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat LOGE("Unable to listen on socket (%s)", strerror(errno)); 62168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 63168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 64168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 65168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 66168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat while(1) { 67168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat fd_set read_fds; 68168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat struct timeval to; 69168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int max = 0; 70168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int rc = 0; 71168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 72168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat to.tv_sec = 60 * 60; 73168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat to.tv_usec = 0; 74168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 75168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat FD_ZERO(&read_fds); 76168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 77168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if ((mAcceptClients == false) || 78168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat (mAcceptClients == true && mCsock == -1)) { 79168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat FD_SET(mSock, &read_fds); 80168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat max = mSock; 81168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if (mCsock != -1) { 82168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat FD_SET(mCsock, &read_fds); 83168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat max = mCsock; 84168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 85168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 86168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) { 87168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat LOGE("select failed (%s)", strerror(errno)); 88168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -errno; 89168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if (!rc) 90168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat continue; 91168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat else if (FD_ISSET(mSock, &read_fds)) { 92168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat /* 93168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * If we're accepting client connections then 94168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * accept and gobble the event. Otherwise 95168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * pass it on to the handlers. 96168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat */ 97168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (mAcceptClients) { 98168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat struct sockaddr addr; 99168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat socklen_t alen = sizeof(addr); 100168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 101168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if ((mCsock = accept(mSock, &addr, &alen)) < 0) { 102168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat LOGE("accept failed (%s)", strerror(errno)); 103168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -errno; 104168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 105168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat LOGD("SocketListener client connection accepted"); 106168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if (!onDataAvailable(mSock)) { 107168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat LOGW("SocketListener closing listening socket (Will shut down)"); 108168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat close(mSock); 109168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -ESHUTDOWN; 110168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 111168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if ((FD_ISSET(mCsock, &read_fds)) && 112168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat !onDataAvailable(mCsock)) { 113168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat /* 114168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Once mCsock == -1, we'll start 115168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * accepting connections on mSock again. 116168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat */ 117168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat LOGD("SocketListener closing client socket"); 118168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat close(mCsock); 119168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mCsock = -1; 120168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 121168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 122168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return 0; 123168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 124168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 125168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehatbool SocketListener::onDataAvailable(int socket) { 126168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return false; 127168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 128