X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust-comm%2Flttng-ust-comm.c;h=1e9972d2461f77c617c6f67864d8fe019caa2f7b;hb=f680d83cec4c2f9c3caa6067f805a45c06f91657;hp=7a87ff1a7215edfff2ebe52cb871a9bf88ba7e8b;hpb=256e8c983f7c3999ec0f54764afd06aa08d47ae9;p=lttng-ust.git diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c index 7a87ff1a..1e9972d2 100644 --- a/liblttng-ust-comm/lttng-ust-comm.c +++ b/liblttng-ust-comm/lttng-ust-comm.c @@ -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 != EPERM) + && 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) { /* @@ -830,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 = <tng_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. */ @@ -915,6 +968,8 @@ int ustcomm_register_event(int sock, if (len < 0) { return len; } + } else { + free(fields); } if (model_emf_uri_len) { @@ -968,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) */ { @@ -982,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; @@ -993,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; @@ -1021,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));