SocketClient.cpp revision 648ebad883e7825353c841950dd7d78664c238e6
1#include <alloca.h> 2#include <errno.h> 3#include <sys/socket.h> 4#include <sys/types.h> 5#include <pthread.h> 6#include <string.h> 7 8#define LOG_TAG "SocketClient" 9#include <cutils/log.h> 10 11#include <sysutils/SocketClient.h> 12 13SocketClient::SocketClient(int socket) 14 : mSocket(socket) 15 , mPid(-1) 16 , mUid(-1) 17 , mGid(-1) 18 , mRefCount(1) 19{ 20 pthread_mutex_init(&mWriteMutex, NULL); 21 pthread_mutex_init(&mRefCountMutex, NULL); 22 23 struct ucred creds; 24 socklen_t szCreds = sizeof(creds); 25 memset(&creds, 0, szCreds); 26 27 int err = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); 28 if (err == 0) { 29 mPid = creds.pid; 30 mUid = creds.uid; 31 mGid = creds.gid; 32 } 33} 34 35int SocketClient::sendMsg(int code, const char *msg, bool addErrno) { 36 char *buf; 37 const char* arg; 38 const char* fmt; 39 char tmp[1]; 40 int len; 41 42 if (addErrno) { 43 fmt = "%.3d %s (%s)"; 44 arg = strerror(errno); 45 } else { 46 fmt = "%.3d %s"; 47 arg = NULL; 48 } 49 /* Measure length of required buffer */ 50 len = snprintf(tmp, sizeof tmp, fmt, code, msg, arg); 51 /* Allocate in the stack, then write to it */ 52 buf = (char*)alloca(len+1); 53 snprintf(buf, len+1, fmt, code, msg, arg); 54 /* Send the zero-terminated message */ 55 return sendMsg(buf); 56} 57 58int SocketClient::sendMsg(const char *msg) { 59 if (mSocket < 0) { 60 errno = EHOSTUNREACH; 61 return -1; 62 } 63 64 // Send the message including null character 65 if (sendData(msg, strlen(msg) + 1) != 0) { 66 SLOGW("Unable to send msg '%s'", msg); 67 return -1; 68 } 69 return 0; 70} 71 72int SocketClient::sendData(const void* data, int len) { 73 int rc = 0; 74 const char *p = (const char*) data; 75 int brtw = len; 76 77 if (len == 0) { 78 return 0; 79 } 80 81 pthread_mutex_lock(&mWriteMutex); 82 while (brtw > 0) { 83 rc = write(mSocket, p, brtw); 84 if (rc > 0) { 85 p += rc; 86 brtw -= rc; 87 continue; 88 } 89 90 if (rc < 0 && errno == EINTR) 91 continue; 92 93 pthread_mutex_unlock(&mWriteMutex); 94 if (rc == 0) { 95 SLOGW("0 length write :("); 96 errno = EIO; 97 } else { 98 SLOGW("write error (%s)", strerror(errno)); 99 } 100 return -1; 101 } 102 pthread_mutex_unlock(&mWriteMutex); 103 return 0; 104} 105 106void SocketClient::incRef() { 107 pthread_mutex_lock(&mRefCountMutex); 108 mRefCount++; 109 pthread_mutex_unlock(&mRefCountMutex); 110} 111 112void SocketClient::decRef() { 113 bool deleteSelf = false; 114 pthread_mutex_lock(&mRefCountMutex); 115 mRefCount--; 116 if (mRefCount == 0) { 117 deleteSelf = true; 118 } 119 pthread_mutex_unlock(&mRefCountMutex); 120 if (deleteSelf) { 121 delete this; 122 } 123} 124