Fix socket message handling 01/145201/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 21 Aug 2017 14:24:37 +0000 (17:24 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 21 Aug 2017 14:52:37 +0000 (17:52 +0300)
Change-Id: I8242a9e1b1168133ae347dc8c3d2669d78975cde
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
helper/libdaprobe.c

index bbae52cc4bbdbf8bdfd810bedaa43304f27ff87c..58a2ef264fdd98d288f6e7034c529bfbe2ea7b57 100755 (executable)
@@ -43,6 +43,7 @@
 #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 */
@@ -156,13 +157,55 @@ void application_exit()
        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;
@@ -203,62 +246,32 @@ static int create_socket(void)
        /* 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");
@@ -293,33 +306,6 @@ pid_t _gettid()
        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;
@@ -327,7 +313,6 @@ static void *recv_thread(void __unused * data)
        uint64_t xtime;
        ssize_t recvlen;
        log_t log;
-       char *data_buf = NULL;
        sigset_t profsigmask;
 
        if (gTraceInfo.socket.daemonSock == -1)
@@ -365,30 +350,24 @@ static void *recv_thread(void __unused * data)
                        }
                        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);
@@ -402,24 +381,16 @@ static void *recv_thread(void __unused * data)
                        } 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;
                }