1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <stdio.h> 17 #include <errno.h> 18 #include <stdlib.h> 19 #include <sys/socket.h> 20 #include <sys/select.h> 21 #include <sys/time.h> 22 #include <sys/types.h> 23 #include <sys/un.h> 24 25 #define LOG_TAG "SocketListener" 26 #include <cutils/log.h> 27 #include <cutils/sockets.h> 28 29 #include <sysutils/SocketListener.h> 30 #include <sysutils/SocketClient.h> 31 32 SocketListener::SocketListener(const char *socketName, bool listen) { 33 mListen = listen; 34 mSocketName = socketName; 35 mSock = -1; 36 pthread_mutex_init(&mClientsLock, NULL); 37 mClients = new SocketClientCollection(); 38 } 39 40 SocketListener::SocketListener(int socketFd, bool listen) { 41 mListen = listen; 42 mSocketName = NULL; 43 mSock = socketFd; 44 pthread_mutex_init(&mClientsLock, NULL); 45 mClients = new SocketClientCollection(); 46 } 47 48 SocketListener::~SocketListener() { 49 if (mSocketName && mSock > -1) 50 close(mSock); 51 52 if (mCtrlPipe[0] != -1) { 53 close(mCtrlPipe[0]); 54 close(mCtrlPipe[1]); 55 } 56 SocketClientCollection::iterator it; 57 for (it = mClients->begin(); it != mClients->end(); ++it) { 58 delete (*it); 59 it = mClients->erase(it); 60 } 61 delete mClients; 62 } 63 64 int SocketListener::startListener() { 65 66 if (!mSocketName && mSock == -1) { 67 SLOGE("Failed to start unbound listener"); 68 errno = EINVAL; 69 return -1; 70 } else if (mSocketName) { 71 if ((mSock = android_get_control_socket(mSocketName)) < 0) { 72 SLOGE("Obtaining file descriptor socket '%s' failed: %s", 73 mSocketName, strerror(errno)); 74 return -1; 75 } 76 } 77 78 if (mListen && listen(mSock, 4) < 0) { 79 SLOGE("Unable to listen on socket (%s)", strerror(errno)); 80 return -1; 81 } else if (!mListen) 82 mClients->push_back(new SocketClient(mSock)); 83 84 if (pipe(mCtrlPipe)) { 85 SLOGE("pipe failed (%s)", strerror(errno)); 86 return -1; 87 } 88 89 if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) { 90 SLOGE("pthread_create (%s)", strerror(errno)); 91 return -1; 92 } 93 94 return 0; 95 } 96 97 int SocketListener::stopListener() { 98 char c = 0; 99 100 if (write(mCtrlPipe[1], &c, 1) != 1) { 101 SLOGE("Error writing to control pipe (%s)", strerror(errno)); 102 return -1; 103 } 104 105 void *ret; 106 if (pthread_join(mThread, &ret)) { 107 SLOGE("Error joining to listener thread (%s)", strerror(errno)); 108 return -1; 109 } 110 close(mCtrlPipe[0]); 111 close(mCtrlPipe[1]); 112 mCtrlPipe[0] = -1; 113 mCtrlPipe[1] = -1; 114 115 if (mSocketName && mSock > -1) { 116 close(mSock); 117 mSock = -1; 118 } 119 120 SocketClientCollection::iterator it; 121 for (it = mClients->begin(); it != mClients->end(); ++it) { 122 delete (*it); 123 it = mClients->erase(it); 124 } 125 return 0; 126 } 127 128 void *SocketListener::threadStart(void *obj) { 129 SocketListener *me = reinterpret_cast<SocketListener *>(obj); 130 131 me->runListener(); 132 pthread_exit(NULL); 133 return NULL; 134 } 135 136 void SocketListener::runListener() { 137 138 while(1) { 139 SocketClientCollection::iterator it; 140 fd_set read_fds; 141 int rc = 0; 142 int max = 0; 143 144 FD_ZERO(&read_fds); 145 146 if (mListen) { 147 max = mSock; 148 FD_SET(mSock, &read_fds); 149 } 150 151 FD_SET(mCtrlPipe[0], &read_fds); 152 if (mCtrlPipe[0] > max) 153 max = mCtrlPipe[0]; 154 155 pthread_mutex_lock(&mClientsLock); 156 for (it = mClients->begin(); it != mClients->end(); ++it) { 157 FD_SET((*it)->getSocket(), &read_fds); 158 if ((*it)->getSocket() > max) 159 max = (*it)->getSocket(); 160 } 161 pthread_mutex_unlock(&mClientsLock); 162 163 if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) { 164 SLOGE("select failed (%s)", strerror(errno)); 165 sleep(1); 166 continue; 167 } else if (!rc) 168 continue; 169 170 if (FD_ISSET(mCtrlPipe[0], &read_fds)) 171 break; 172 if (mListen && FD_ISSET(mSock, &read_fds)) { 173 struct sockaddr addr; 174 socklen_t alen = sizeof(addr); 175 int c; 176 177 if ((c = accept(mSock, &addr, &alen)) < 0) { 178 SLOGE("accept failed (%s)", strerror(errno)); 179 sleep(1); 180 continue; 181 } 182 pthread_mutex_lock(&mClientsLock); 183 mClients->push_back(new SocketClient(c)); 184 pthread_mutex_unlock(&mClientsLock); 185 } 186 187 do { 188 pthread_mutex_lock(&mClientsLock); 189 for (it = mClients->begin(); it != mClients->end(); ++it) { 190 int fd = (*it)->getSocket(); 191 if (FD_ISSET(fd, &read_fds)) { 192 pthread_mutex_unlock(&mClientsLock); 193 if (!onDataAvailable(*it)) { 194 close(fd); 195 pthread_mutex_lock(&mClientsLock); 196 delete *it; 197 it = mClients->erase(it); 198 pthread_mutex_unlock(&mClientsLock); 199 } 200 FD_CLR(fd, &read_fds); 201 pthread_mutex_lock(&mClientsLock); 202 continue; 203 } 204 } 205 pthread_mutex_unlock(&mClientsLock); 206 } while (0); 207 } 208 } 209 210 void SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) { 211 pthread_mutex_lock(&mClientsLock); 212 SocketClientCollection::iterator i; 213 214 for (i = mClients->begin(); i != mClients->end(); ++i) { 215 if ((*i)->sendMsg(code, msg, addErrno)) { 216 SLOGW("Error sending broadcast (%s)", strerror(errno)); 217 } 218 } 219 pthread_mutex_unlock(&mClientsLock); 220 } 221 222 void SocketListener::sendBroadcast(const char *msg) { 223 pthread_mutex_lock(&mClientsLock); 224 SocketClientCollection::iterator i; 225 226 for (i = mClients->begin(); i != mClients->end(); ++i) { 227 if ((*i)->sendMsg(msg)) { 228 SLOGW("Error sending broadcast (%s)", strerror(errno)); 229 } 230 } 231 pthread_mutex_unlock(&mClientsLock); 232 } 233