#include <pthread.h> /* for pthread_mutex_lock */
#include <signal.h>
#include <stdint.h>
+#include <errno.h>
#include <sys/syscall.h> /* for syscall */
#include <sys/time.h> /* for gettimeofday */
killpg(gpid, SIGKILL);
}
+static int do_read(int fd, void *data, size_t size)
+{
+ ssize_t n;
+
+ do {
+ n = recv(fd, data, size, MSG_WAITALL);
+ } while (n == -1 && errno == EINTR);
+
+ if (n == -1)
+ return -errno;
+ else if ((size_t)n != size)
+ return -EBUSY;
+
+ return 0;
+}
+
+static int read_log(int fd, log_t *log)
+{
+ const size_t HEADER_SIZE = sizeof(log->type) + sizeof(log->length);
+ int ret;
+
+ /* read_header */
+ ret = do_read(fd, log, HEADER_SIZE);
+ if (ret)
+ return ret;
+
+ /* check length */
+ if ((size_t)log->length > sizeof(log->data)) {
+ PRINTERR("msg is too long: type=%u len=%u\n",
+ log->type, log->length);
+ return -EINVAL;
+ }
+
+ /* check payload */
+ if (log->length == 0)
+ return 0;
+
+ /* read payload */
+ ret = do_read(fd, log->data, log->length);
+
+ return ret;
+}
+
/* create socket to daemon and connect */
#define MSG_CONFIG_RECV 0x01
#define MSG_TARGET_BINS_RECV 0x02
static int create_socket(void)
{
char strerr_buf[MAX_PATH_LENGTH];
- ssize_t recvlen;
int client_len, ret = 0;
struct sockaddr_un client_addr;
log_t log;
/* we need recv this messages right now! */
while (((recved & MSG_CONFIG_RECV) == 0) ||
((recved & MSG_TARGET_BINS_RECV) == 0)) {
+ const char *data_buf;
+
PRINTMSG("wait incoming message %d\n",
gTraceInfo.socket.daemonSock);
- /* recv header */
- recvlen = recv(gTraceInfo.socket.daemonSock, &log,
- sizeof(log.type) + sizeof(log.length),
- MSG_WAITALL);
- fprintf(stderr, "recv %zd\n", recvlen);
- if (recvlen > 0) { /* recv succeed */
- char *data_buf = NULL;
-
- data_buf = malloc(log.length);
- if (data_buf == NULL) {
- PRINTERR("cannot allocate buf to recv msg");
- break;
- }
-
- recvlen = recv(gTraceInfo.socket.daemonSock, data_buf,
- log.length, MSG_WAITALL);
-
- if (recvlen != log.length) {
- PRINTERR("Can not get data from daemon sock\n");
- goto free_data_buf;
- }
- if (log.type == APP_MSG_CONFIG) {
- PRINTMSG("APP_MSG_CONFIG");
- _configure(data_buf);
- recved |= MSG_CONFIG_RECV;
- } else if (log.type == APP_MSG_TARGET_BINS) {
- PRINTMSG("APP_MSG_TARGET_BINS");
- _process_target_bins(data_buf);
- recved |= MSG_TARGET_BINS_RECV;
- } else {
- /* unexpected case */
- PRINTERR("unknown message! %d", log.type);
- }
-
-free_data_buf:
- if (data_buf != NULL)
- free(data_buf);
-
- } else if (recvlen < 0) {
- close(gTraceInfo.socket.daemonSock);
- gTraceInfo.socket.daemonSock = -1;
- PRINTERR("recv failed with error(%d)\n", recvlen);
- ret = -1;
- application_exit();
- break;
- } else {
- /* closed by other peer */
+ ret = read_log(gTraceInfo.socket.daemonSock, &log);
+ if (ret) {
close(gTraceInfo.socket.daemonSock);
gTraceInfo.socket.daemonSock = -1;
PRINTERR("closed by other peer\n");
- ret = -1;
application_exit();
- break;
+ return -1;
+ }
+
+ data_buf = log.data;
+ if (log.type == APP_MSG_CONFIG) {
+ PRINTMSG("APP_MSG_CONFIG");
+ _configure((char *)data_buf);
+ recved |= MSG_CONFIG_RECV;
+ } else if (log.type == APP_MSG_TARGET_BINS) {
+ PRINTMSG("APP_MSG_TARGET_BINS");
+ _process_target_bins((char *)data_buf);
+ recved |= MSG_TARGET_BINS_RECV;
+ } else {
+ // unexpected case
+ PRINTERR("lp: unknown message! %x", log.type);
}
}
PRINTMSG("create_socket connect() success\n");
return gTid;
}
-/* Allocate memory and gets payload for message */
-static char *get_msg_payload(log_t *log)
-{
- char *data_buf = NULL;
- ssize_t recvlen;
-
- if (log->length <= 0)
- return NULL;
-
- data_buf = malloc(log->length);
- if (data_buf == NULL) {
- PRINTERR("Cannot allocate buffer for message. Size %d",
- log->length);
- return NULL;
- }
-
- recvlen = recv(gTraceInfo.socket.daemonSock, data_buf, log->length,
- MSG_WAITALL);
- if (recvlen != log->length) {
- PRINTERR("Cannot receive data!");
- free(data_buf);
- data_buf = NULL;
- }
-
- return data_buf;
-}
-
static void *recv_thread(void __unused * data)
{
fd_set readfds, workfds;
uint64_t xtime;
ssize_t recvlen;
log_t log;
- char *data_buf = NULL;
sigset_t profsigmask;
if (gTraceInfo.socket.daemonSock == -1)
}
continue;
} else if (FD_ISSET(gTraceInfo.socket.daemonSock, &workfds)) {
- recvlen = recv(gTraceInfo.socket.daemonSock, &log,
- sizeof(log.type) + sizeof(log.length),
- MSG_WAITALL);
- if (recvlen == 0) { /* closed by other peer */
+ int ret;
+ const char *data_buf;
+
+ ret = read_log(gTraceInfo.socket.daemonSock, &log);
+ if (ret) {
close(gTraceInfo.socket.daemonSock);
gTraceInfo.socket.daemonSock = -1;
- break;
- } else if (recvlen < 0) { /* recv error */
- PRINTERR("recv failed in recv thread with "
- "error(%d)", recvlen);
- continue;
+ PRINTERR("Invalid log format: ret=%d", ret);
+ return NULL;
}
- /* recv succeed */
+ data_buf = log.data;
if (log.type == APP_MSG_CAPTURE_SCREEN) {
capture_screen_call();
} else if (log.type == APP_MSG_CONFIG) {
- data_buf = get_msg_payload(&log);
- if (data_buf != NULL)
- _configure(data_buf);
+ _configure((char *)data_buf);
} else if (log.type == APP_MSG_TARGET_BINS) {
- data_buf = get_msg_payload(&log);
- if (data_buf != NULL)
- _process_target_bins(data_buf);
+ _process_target_bins((char *)data_buf);
} else if ((log.type == APP_MSG_STOP) ||
(log.type == APP_MSG_STOP_WITHOUT_KILL)) {
PRINTMSG("APP_MSG_STOP (%d)", log.type);
} else if(log.type == APP_MSG_GET_UI_HIERARCHY) {
PRINTMSG("APP_MSG_GET_UI_HIERARCHY");
/* do nothing */
- continue;
} else if(log.type == APP_MSG_GET_UI_SCREENSHOT) {
PRINTMSG("APP_MSG_GET_UI_SCREENSHOT");
/* do nothing */
- continue;
} else if(log.type == APP_MSG_GET_UI_HIERARCHY_CANCEL) {
PRINTMSG("APP_MSG_GET_UI_HIERARCHY_CANCEL");
/* do nothing */
- continue;
} else {
PRINTERR("recv unknown message. id = (%d)",
log.type);
}
-
- if (data_buf) {
- free(data_buf);
- data_buf = NULL;
- }
} else { /* unknown case */
continue;
}