Fix: lttng-ust-comm.c: return number of fd rather size of array
[lttng-ust.git] / liblttng-ust-comm / lttng-ust-comm.c
index 129ad8f259aaa3eea7fea766a567c207fd98797e..5b9cb85381fcb815998c7ecaa733a52a7d2a31e7 100644 (file)
@@ -19,6 +19,7 @@
 
 #define _GNU_SOURCE
 #include <limits.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -33,6 +34,7 @@
 
 #include <lttng/ust-ctl.h>
 #include <ust-comm.h>
+#include <ust-fd.h>
 #include <helper.h>
 #include <lttng/ust-error.h>
 #include <lttng/ust-events.h>
@@ -94,8 +96,10 @@ const char *lttng_ust_strerror(int code)
  * ustcomm_connect_unix_sock
  *
  * Connect to unix socket using the path name.
+ *
+ * Caller handles FD tracker.
  */
-int ustcomm_connect_unix_sock(const char *pathname)
+int ustcomm_connect_unix_sock(const char *pathname, long timeout)
 {
        struct sockaddr_un sun;
        int fd, ret;
@@ -110,6 +114,15 @@ int ustcomm_connect_unix_sock(const char *pathname)
                ret = -errno;
                goto error;
        }
+       if (timeout >= 0) {
+               /* Give at least 10ms. */
+               if (timeout < 10)
+                       timeout = 10;
+               ret = ustcomm_setsockopt_snd_timeout(fd, timeout);
+               if (ret < 0) {
+                       WARN("Error setting connect socket send timeout");
+               }
+       }
        ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
        if (ret < 0) {
                PERROR("fcntl");
@@ -248,16 +261,22 @@ int ustcomm_listen_unix_sock(int sock)
  * ustcomm_close_unix_sock
  *
  * Shutdown cleanly a unix socket.
+ *
+ * Handles fd tracker internally.
  */
 int ustcomm_close_unix_sock(int sock)
 {
        int ret;
 
+       lttng_ust_lock_fd_tracker();
        ret = close(sock);
-       if (ret < 0) {
+       if (!ret) {
+               lttng_ust_delete_fd_from_tracker(sock);
+       } else {
                PERROR("close");
                ret = -errno;
        }
+       lttng_ust_unlock_fd_tracker();
 
        return ret;
 }
@@ -420,8 +439,6 @@ ssize_t ustcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
 /*
  * Recv a message accompanied by fd(s) from a unix socket.
  *
- * Returns the size of received data, or negative error value.
- *
  * Expect at most "nb_fd" file descriptors. Returns the number of fd
  * actually received in nb_fd.
  * Returns -EPIPE on orderly shutdown.
@@ -491,7 +508,7 @@ ssize_t ustcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
                goto end;
        }
        memcpy(fds, CMSG_DATA(cmsg), sizeof_fds);
-       ret = sizeof_fds;
+       ret = nb_fd;
 end:
        return ret;
 }
@@ -580,7 +597,7 @@ ssize_t ustcomm_recv_channel_from_sessiond(int sock,
 {
        void *chan_data;
        ssize_t len, nr_fd;
-       int wakeup_fd;
+       int wakeup_fd, ret;
 
        if (var_len > LTTNG_UST_CHANNEL_DATA_MAX_LEN) {
                len = -EINVAL;
@@ -597,8 +614,10 @@ ssize_t ustcomm_recv_channel_from_sessiond(int sock,
                goto error_recv;
        }
        /* recv wakeup fd */
+       lttng_ust_lock_fd_tracker();
        nr_fd = ustcomm_recv_fds_unix_sock(sock, &wakeup_fd, 1);
        if (nr_fd <= 0) {
+               lttng_ust_unlock_fd_tracker();
                if (nr_fd < 0) {
                        len = nr_fd;
                        goto error_recv;
@@ -607,7 +626,21 @@ ssize_t ustcomm_recv_channel_from_sessiond(int sock,
                        goto error_recv;
                }
        }
-       *_wakeup_fd = wakeup_fd;
+
+       ret = lttng_ust_add_fd_to_tracker(wakeup_fd);
+       if (ret < 0) {
+               ret = close(wakeup_fd);
+               if (ret) {
+                       PERROR("close on wakeup_fd");
+               }
+               len = -EIO;
+               lttng_ust_unlock_fd_tracker();
+               goto error_recv;
+       }
+
+       *_wakeup_fd = ret;
+       lttng_ust_unlock_fd_tracker();
+
        *_chan_data = chan_data;
        return len;
 
@@ -627,8 +660,10 @@ int ustcomm_recv_stream_from_sessiond(int sock,
        int fds[2];
 
        /* recv shm fd and wakeup fd */
+       lttng_ust_lock_fd_tracker();
        len = ustcomm_recv_fds_unix_sock(sock, fds, 2);
        if (len <= 0) {
+               lttng_ust_unlock_fd_tracker();
                if (len < 0) {
                        ret = len;
                        goto error;
@@ -637,8 +672,36 @@ int ustcomm_recv_stream_from_sessiond(int sock,
                        goto error;
                }
        }
-       *shm_fd = fds[0];
-       *wakeup_fd = fds[1];
+
+       ret = lttng_ust_add_fd_to_tracker(fds[0]);
+       if (ret < 0) {
+               ret = close(fds[0]);
+               if (ret) {
+                       PERROR("close on received shm_fd");
+               }
+               ret = -EIO;
+               lttng_ust_unlock_fd_tracker();
+               goto error;
+       }
+       *shm_fd = ret;
+
+       ret = lttng_ust_add_fd_to_tracker(fds[1]);
+       if (ret < 0) {
+               ret = close(*shm_fd);
+               if (ret) {
+                       PERROR("close on shm_fd");
+               }
+               *shm_fd = -1;
+               ret = close(fds[1]);
+               if (ret) {
+                       PERROR("close on received wakeup_fd");
+               }
+               ret = -EIO;
+               lttng_ust_unlock_fd_tracker();
+               goto error;
+       }
+       *wakeup_fd = ret;
+       lttng_ust_unlock_fd_tracker();
        return 0;
 
 error:
@@ -789,12 +852,15 @@ static
 int serialize_integer_type(struct ustctl_integer_type *uit,
                const struct lttng_integer_type *lit)
 {
+       int32_t encoding;
+
        uit->size = lit->size;
        uit->signedness = lit->signedness;
        uit->reverse_byte_order = lit->reverse_byte_order;
        uit->base = lit->base;
-       if (serialize_string_encoding(&uit->encoding, lit->encoding))
+       if (serialize_string_encoding(&encoding, lit->encoding))
                return -EINVAL;
+       uit->encoding = encoding;
        uit->alignment = lit->alignment;
        return 0;
 }
@@ -816,9 +882,11 @@ int serialize_basic_type(struct lttng_session *session,
        }
        case atype_string:
        {
-               if (serialize_string_encoding(&ubt->string.encoding,
-                               lbt->string.encoding))
+               int32_t encoding;
+
+               if (serialize_string_encoding(&encoding, lbt->string.encoding))
                        return -EINVAL;
+               ubt->string.encoding = encoding;
                *uatype = ustctl_atype_string;
                break;
        }
@@ -847,8 +915,7 @@ int serialize_basic_type(struct lttng_session *session,
                if (session) {
                        const struct lttng_enum *_enum;
 
-                       _enum = lttng_ust_enum_get(session,
-                                       lbt->enumeration.desc->name);
+                       _enum = lttng_ust_enum_get_from_desc(session, lbt->enumeration.desc);
                        if (!_enum)
                                return -EINVAL;
                        ubt->enumeration.id = _enum->id;
@@ -944,13 +1011,15 @@ int serialize_one_field(struct lttng_session *session,
        {
                struct ustctl_field *uf = &fields[*iter_output];
                struct ustctl_type *ut = &uf->type;
+               enum ustctl_abstract_types atype;
 
                strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
                uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
-               ret = serialize_basic_type(session, &ut->atype, lt->atype,
+               ret = serialize_basic_type(session, &atype, lt->atype,
                        &ut->u.basic, &lt->u.basic);
                if (ret)
                        return ret;
+               ut->atype = atype;
                (*iter_output)++;
                break;
        }
@@ -960,6 +1029,7 @@ int serialize_one_field(struct lttng_session *session,
                struct ustctl_type *ut = &uf->type;
                struct ustctl_basic_type *ubt;
                const struct lttng_basic_type *lbt;
+               enum ustctl_abstract_types atype;
 
                strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
                uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
@@ -967,10 +1037,11 @@ int serialize_one_field(struct lttng_session *session,
                ubt = &ut->u.array.elem_type;
                lbt = &lt->u.array.elem_type;
                ut->u.array.length = lt->u.array.length;
-               ret = serialize_basic_type(session, &ubt->atype, lbt->atype,
+               ret = serialize_basic_type(session, &atype, lbt->atype,
                        &ubt->u.basic, &lbt->u.basic);
                if (ret)
                        return -EINVAL;
+               ubt->atype = atype;
                ut->atype = ustctl_atype_array;
                (*iter_output)++;
                break;
@@ -981,6 +1052,7 @@ int serialize_one_field(struct lttng_session *session,
                struct ustctl_type *ut = &uf->type;
                struct ustctl_basic_type *ubt;
                const struct lttng_basic_type *lbt;
+               enum ustctl_abstract_types atype;
                int ret;
 
                strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
@@ -988,16 +1060,18 @@ int serialize_one_field(struct lttng_session *session,
                uf->type.atype = ustctl_atype_sequence;
                ubt = &ut->u.sequence.length_type;
                lbt = &lt->u.sequence.length_type;
-               ret = serialize_basic_type(session, &ubt->atype, lbt->atype,
+               ret = serialize_basic_type(session, &atype, lbt->atype,
                        &ubt->u.basic, &lbt->u.basic);
                if (ret)
                        return -EINVAL;
+               ubt->atype = atype;
                ubt = &ut->u.sequence.elem_type;
                lbt = &lt->u.sequence.elem_type;
-               ret = serialize_basic_type(session, &ubt->atype, lbt->atype,
+               ret = serialize_basic_type(session, &atype, lbt->atype,
                        &ubt->u.basic, &lbt->u.basic);
                if (ret)
                        return -EINVAL;
+               ubt->atype = atype;
                ut->atype = ustctl_atype_sequence;
                (*iter_output)++;
                break;
This page took 0.026616 seconds and 4 git commands to generate.