Version 2.5.7
[lttng-ust.git] / liblttng-ust-comm / lttng-ust-comm.c
index 00b1d43af0a4ec1610e4d1a83d204a2c064236b3..1e9972d2461f77c617c6f67864d8fe019caa2f7b 100644 (file)
@@ -123,7 +123,7 @@ int ustcomm_connect_unix_sock(const char *pathname)
                 * file exists but no sessiond is listening.
                 */
                if (errno != ECONNREFUSED && errno != ECONNRESET
-                               && errno != ENOENT)
+                               && errno != ENOENT && errno != EACCES)
                        PERROR("connect");
                ret = -errno;
                if (ret == -ECONNREFUSED || ret == -ECONNRESET)
@@ -265,7 +265,8 @@ ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len)
 {
        struct msghdr msg;
        struct iovec iov[1];
-       ssize_t ret;
+       ssize_t ret = -1;
+       size_t len_last;
 
        memset(&msg, 0, sizeof(msg));
 
@@ -275,8 +276,14 @@ ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len)
        msg.msg_iovlen = 1;
 
        do {
+               len_last = iov[0].iov_len;
                ret = recvmsg(sock, &msg, 0);
-       } while (ret < 0 && errno == EINTR);
+               if (ret > 0) {
+                       iov[0].iov_base += ret;
+                       iov[0].iov_len -= ret;
+                       assert(ret <= len_last);
+               }
+       } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR));
 
        if (ret < 0) {
                int shutret;
@@ -290,7 +297,10 @@ ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len)
                shutret = shutdown(sock, SHUT_RDWR);
                if (shutret)
                        ERR("Socket shutdown error");
+       } else if (ret > 0) {
+               ret = len;
        }
+       /* ret = 0 means an orderly shutdown. */
 
        return ret;
 }
@@ -367,6 +377,8 @@ ssize_t ustcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        msg.msg_controllen = CMSG_LEN(sizeof_fds);
 
        cmptr = CMSG_FIRSTHDR(&msg);
+       if (!cmptr)
+               return -EINVAL;
        cmptr->cmsg_level = SOL_SOCKET;
        cmptr->cmsg_type = SCM_RIGHTS;
        cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
@@ -380,7 +392,7 @@ ssize_t ustcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        msg.msg_iovlen = 1;
 
        do {
-               ret = sendmsg(sock, &msg, 0);
+               ret = sendmsg(sock, &msg, MSG_NOSIGNAL);
        } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
                /*
@@ -656,6 +668,26 @@ int ustcomm_send_reg_msg(int sock,
        return 0;
 }
 
+static
+int serialize_string_encoding(enum ustctl_string_encodings *ue,
+               enum lttng_string_encodings le)
+{
+       switch (le) {
+       case lttng_encode_none:
+               *ue = ustctl_encode_none;
+               break;
+       case lttng_encode_UTF8:
+               *ue = ustctl_encode_UTF8;
+               break;
+       case lttng_encode_ASCII:
+               *ue = ustctl_encode_ASCII;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static
 int serialize_basic_type(enum ustctl_abstract_types *uatype,
                enum lttng_abstract_types atype,
@@ -674,14 +706,17 @@ int serialize_basic_type(enum ustctl_abstract_types *uatype,
                uit->signedness = lit->signedness;
                uit->reverse_byte_order = lit->reverse_byte_order;
                uit->base = lit->base;
-               uit->encoding = lit->encoding;
+               if (serialize_string_encoding(&uit->encoding, lit->encoding))
+                       return -EINVAL;
                uit->alignment = lit->alignment;
                *uatype = ustctl_atype_integer;
                break;
        }
        case atype_string:
        {
-               ubt->string.encoding = lbt->string.encoding;
+               if (serialize_string_encoding(&ubt->string.encoding,
+                               lbt->string.encoding))
+                       return -EINVAL;
                *uatype = ustctl_atype_string;
                break;
        }
@@ -807,6 +842,47 @@ error_type:
        return ret;
 }
 
+static
+int serialize_ctx_fields(size_t *_nr_write_fields,
+               struct ustctl_field **ustctl_fields,
+               size_t nr_fields,
+               const struct lttng_ctx_field *lttng_fields)
+{
+       struct ustctl_field *fields;
+       int i, ret;
+       size_t nr_write_fields = 0;
+
+       fields = zmalloc(nr_fields * sizeof(*fields));
+       if (!fields)
+               return -ENOMEM;
+
+       for (i = 0; i < nr_fields; i++) {
+               struct ustctl_field *f;
+               const struct lttng_event_field *lf;
+
+               f = &fields[nr_write_fields];
+               lf = &lttng_fields[i].event_field;
+
+               /* skip 'nowrite' fields */
+               if (lf->nowrite)
+                       continue;
+               strncpy(f->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
+               f->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+               ret = serialize_one_type(&f->type, &lf->type);
+               if (ret)
+                       goto error_type;
+               nr_write_fields++;
+       }
+
+       *_nr_write_fields = nr_write_fields;
+       *ustctl_fields = fields;
+       return 0;
+
+error_type:
+       free(fields);
+       return ret;
+}
+
 /*
  * Returns 0 on success, negative error value on error.
  */
@@ -831,7 +907,7 @@ int ustcomm_register_event(int sock,
                struct ustcomm_notify_event_reply r;
        } reply;
        size_t signature_len, fields_len, model_emf_uri_len;
-       struct ustctl_field *fields;
+       struct ustctl_field *fields = NULL;
        size_t nr_write_fields = 0;
        int ret;
 
@@ -892,6 +968,8 @@ int ustcomm_register_event(int sock,
                if (len < 0) {
                        return len;
                }
+       } else {
+               free(fields);
        }
 
        if (model_emf_uri_len) {
@@ -945,7 +1023,7 @@ int ustcomm_register_channel(int sock,
        int session_objd,               /* session descriptor */
        int channel_objd,               /* channel descriptor */
        size_t nr_ctx_fields,
-       const struct lttng_event_field *ctx_fields,
+       const struct lttng_ctx_field *ctx_fields,
        uint32_t *chan_id,              /* channel id (output) */
        int *header_type)               /* header type (output) */
 {
@@ -959,7 +1037,7 @@ int ustcomm_register_channel(int sock,
                struct ustcomm_notify_channel_reply r;
        } reply;
        size_t fields_len;
-       struct ustctl_field *fields;
+       struct ustctl_field *fields = NULL;
        int ret;
        size_t nr_write_fields = 0;
 
@@ -970,7 +1048,7 @@ int ustcomm_register_channel(int sock,
 
        /* Calculate fields len, serialize fields. */
        if (nr_ctx_fields > 0) {
-               ret = serialize_fields(&nr_write_fields, &fields,
+               ret = serialize_ctx_fields(&nr_write_fields, &fields,
                                nr_ctx_fields, ctx_fields);
                if (ret)
                        return ret;
@@ -998,6 +1076,8 @@ int ustcomm_register_channel(int sock,
                if (len < 0) {
                        return len;
                }
+       } else {
+               free(fields);
        }
 
        len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
This page took 0.025442 seconds and 4 git commands to generate.