SocketClient.cpp revision af61509b50bc110b0c7c4691e37873cc0987ab5c
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{ 19 pthread_mutex_init(&mWriteMutex, NULL); 20 21 struct ucred creds; 22 socklen_t szCreds = sizeof(creds); 23 memset(&creds, 0, szCreds); 24 25 int err = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); 26 if (err == 0) { 27 mPid = creds.pid; 28 mUid = creds.uid; 29 mGid = creds.gid; 30 } 31} 32 33int SocketClient::sendMsg(int code, const char *msg, bool addErrno) { 34 char *buf; 35 const char* arg; 36 const char* fmt; 37 char tmp[1]; 38 int len; 39 40 if (addErrno) { 41 fmt = "%.3d %s (%s)"; 42 arg = strerror(errno); 43 } else { 44 fmt = "%.3d %s"; 45 arg = NULL; 46 } 47 /* Measure length of required buffer */ 48 len = snprintf(tmp, sizeof tmp, fmt, code, msg, arg); 49 /* Allocate in the stack, then write to it */ 50 buf = (char*)alloca(len+1); 51 snprintf(buf, len+1, fmt, code, msg, arg); 52 /* Send the zero-terminated message */ 53 return sendMsg(buf); 54} 55 56int SocketClient::sendMsg(const char *msg) { 57 if (mSocket < 0) { 58 errno = EHOSTUNREACH; 59 return -1; 60 } 61 62 // Send the message including null character 63 if (sendData(msg, strlen(msg) + 1) != 0) { 64 SLOGW("Unable to send msg '%s'", msg); 65 return -1; 66 } 67 return 0; 68} 69 70int SocketClient::sendData(const void* data, int len) { 71 int rc = 0; 72 const char *p = (const char*) data; 73 int brtw = len; 74 75 if (len == 0) { 76 return 0; 77 } 78 79 pthread_mutex_lock(&mWriteMutex); 80 while (brtw > 0) { 81 rc = write(mSocket, p, brtw); 82 if (rc > 0) { 83 p += rc; 84 brtw -= rc; 85 continue; 86 } 87 88 if (rc < 0 && errno == EINTR) 89 continue; 90 91 pthread_mutex_unlock(&mWriteMutex); 92 if (rc == 0) { 93 SLOGW("0 length write :("); 94 errno = EIO; 95 } else { 96 SLOGW("write error (%s)", strerror(errno)); 97 } 98 return -1; 99 } 100 pthread_mutex_unlock(&mWriteMutex); 101 return 0; 102} 103