Fix: fclose return value unchecked
[babeltrace.git] / formats / lttng-live / lttng-live-comm.c
index f9ed51e1b3a1aaa9829309e01ce10aac5649e2f7..842eae0840661f1b5ebf972a728e355db49a7e38 100644 (file)
@@ -49,6 +49,8 @@
 #include <babeltrace/ctf/events-internal.h>
 #include <formats/ctf/events-private.h>
 
+#include <babeltrace/compat/memstream.h>
+
 #include "lttng-live.h"
 #include "lttng-viewer-abi.h"
 
@@ -66,6 +68,9 @@ static void ctf_live_packet_seek(struct bt_stream_pos *stream_pos,
                size_t index, int whence);
 static void add_traces(gpointer key, gpointer value, gpointer user_data);
 static int del_traces(gpointer key, gpointer value, gpointer user_data);
+static int get_new_metadata(struct lttng_live_ctx *ctx,
+               struct lttng_live_viewer_stream *viewer_stream,
+               char **metadata_buf);
 
 int lttng_live_connect_viewer(struct lttng_live_ctx *ctx)
 {
@@ -346,6 +351,22 @@ int lttng_live_ctf_trace_assign(struct lttng_live_viewer_stream *stream,
        return ret;
 }
 
+static
+int open_metadata_fp_write(struct lttng_live_viewer_stream *stream,
+               char **metadata_buf, size_t *size)
+{
+       int ret = 0;
+
+       stream->metadata_fp_write =
+               babeltrace_open_memstream(metadata_buf, size);
+       if (!stream->metadata_fp_write) {
+               perror("Metadata open_memstream");
+               ret = -1;
+       }
+
+       return ret;
+}
+
 int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id)
 {
        struct lttng_viewer_cmd cmd;
@@ -471,35 +492,7 @@ int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id)
                ctx->session->streams[i].mmap_size = 0;
 
                if (be32toh(stream.metadata_flag)) {
-                       char *path;
-
-                       path = strdup(LTTNG_METADATA_PATH_TEMPLATE);
-                       if (!path) {
-                               perror("strdup");
-                               ret = -1;
-                               goto error;
-                       }
-                       if (!mkdtemp(path)) {
-                               perror("mkdtemp");
-                               free(path);
-                               ret = -1;
-                               goto error;
-                       }
                        ctx->session->streams[i].metadata_flag = 1;
-                       snprintf(ctx->session->streams[i].path,
-                                       sizeof(ctx->session->streams[i].path),
-                                       "%s/%s", path,
-                                       stream.channel_name);
-                       ret = open(ctx->session->streams[i].path,
-                                       O_WRONLY | O_CREAT | O_TRUNC,
-                                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-                       if (ret < 0) {
-                               perror("open");
-                               free(path);
-                               goto error;
-                       }
-                       ctx->session->streams[i].fd = ret;
-                       free(path);
                }
                ret = lttng_live_ctf_trace_assign(&ctx->session->streams[i],
                                be64toh(stream.ctf_trace_id));
@@ -553,6 +546,43 @@ end:
        return ret;
 }
 
+static
+int append_metadata(struct lttng_live_ctx *ctx,
+               struct lttng_live_viewer_stream *viewer_stream)
+{
+       int ret;
+       struct lttng_live_viewer_stream *metadata;
+       char *metadata_buf = NULL;
+
+       printf_verbose("get_next_index: new metadata needed\n");
+       ret = get_new_metadata(ctx, viewer_stream, &metadata_buf);
+       if (ret < 0) {
+               free(metadata_buf);
+               goto error;
+       }
+
+       metadata = viewer_stream->ctf_trace->metadata_stream;
+       metadata->ctf_trace->metadata_fp =
+               babeltrace_fmemopen(metadata_buf,
+                               metadata->metadata_len, "rb");
+       if (!metadata->ctf_trace->metadata_fp) {
+               perror("Metadata fmemopen");
+               free(metadata_buf);
+               ret = -1;
+               goto error;
+       }
+       ret = ctf_append_trace_metadata(
+                       viewer_stream->ctf_trace->handle->td,
+                       metadata->ctf_trace->metadata_fp);
+       if (ret != 0) {
+               fprintf(stderr, "[error] Appending metadata\n");
+               goto error;
+       }
+
+error:
+       return ret;
+}
+
 static
 int get_data_packet(struct lttng_live_ctx *ctx,
                struct ctf_stream_pos *pos,
@@ -565,6 +595,7 @@ int get_data_packet(struct lttng_live_ctx *ctx,
        ssize_t ret_len;
        int ret;
 
+retry:
        cmd.cmd = htobe32(LTTNG_VIEWER_GET_PACKET);
        cmd.data_size = sizeof(rq);
        cmd.cmd_version = 0;
@@ -631,8 +662,10 @@ int get_data_packet(struct lttng_live_ctx *ctx,
        case LTTNG_VIEWER_GET_PACKET_ERR:
                if (rp.flags & LTTNG_VIEWER_FLAG_NEW_METADATA) {
                        printf_verbose("get_data_packet: new metadata needed\n");
-                       ret = 0;
-                       goto end;
+                       ret = append_metadata(ctx, stream);
+                       if (ret)
+                               goto error;
+                       goto retry;
                }
                if (rp.flags & LTTNG_VIEWER_FLAG_NEW_STREAM) {
                        ret = ask_new_streams(ctx);
@@ -710,30 +743,23 @@ error:
        return ret;
 }
 
-/*
- * Return number of metadata bytes written or a negative value on error.
- */
 static
-int get_new_metadata(struct lttng_live_ctx *ctx,
-               struct lttng_live_viewer_stream *viewer_stream,
-               uint64_t *metadata_len)
+int get_one_metadata_packet(struct lttng_live_ctx *ctx,
+               struct lttng_live_viewer_stream *metadata_stream)
 {
        uint64_t len = 0;
        int ret;
        struct lttng_viewer_cmd cmd;
        struct lttng_viewer_get_metadata rq;
        struct lttng_viewer_metadata_packet rp;
-       struct lttng_live_viewer_stream *metadata_stream;
        char *data = NULL;
        ssize_t ret_len;
 
+       rq.stream_id = htobe64(metadata_stream->id);
        cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA);
        cmd.data_size = sizeof(rq);
        cmd.cmd_version = 0;
 
-       metadata_stream = viewer_stream->ctf_trace->metadata_stream;
-       rq.stream_id = htobe64(metadata_stream->id);
-
        do {
                ret_len = send(ctx->control_sock, &cmd, sizeof(cmd), 0);
        } while (ret_len < 0 && errno == EINTR);
@@ -775,7 +801,7 @@ int get_new_metadata(struct lttng_live_ctx *ctx,
                        break;
                case LTTNG_VIEWER_NO_NEW_METADATA:
                        printf_verbose("get_metadata : NO NEW\n");
-                       ret = -1;
+                       ret = 0;
                        goto end;
                case LTTNG_VIEWER_METADATA_ERR:
                        printf_verbose("get_metadata : ERR\n");
@@ -818,24 +844,67 @@ int get_new_metadata(struct lttng_live_ctx *ctx,
        assert(ret_len == len);
 
        do {
-               ret_len = write(metadata_stream->fd, data, len);
+               ret_len = fwrite(data, 1, len,
+                               metadata_stream->metadata_fp_write);
        } while (ret_len < 0 && errno == EINTR);
        if (ret_len < 0) {
+               fprintf(stderr, "[error] Writing in the metadata fp\n");
                free(data);
                ret = ret_len;
                goto error;
        }
        assert(ret_len == len);
+       metadata_stream->metadata_len += len;
+       ret = len;
 
        free(data);
 
-       *metadata_len = len;
-       ret = 0;
 end:
 error:
        return ret;
 }
 
+/*
+ * Return 0 on success, a negative value on error.
+ */
+static
+int get_new_metadata(struct lttng_live_ctx *ctx,
+               struct lttng_live_viewer_stream *viewer_stream,
+               char **metadata_buf)
+{
+       int ret = 0;
+       struct lttng_live_viewer_stream *metadata_stream;
+       size_t size;
+
+       metadata_stream = viewer_stream->ctf_trace->metadata_stream;
+       if (!metadata_stream) {
+               fprintf(stderr, "[error] No metadata stream\n");
+               ret = -1;
+               goto error;
+       }
+       metadata_stream->metadata_len = 0;
+       ret = open_metadata_fp_write(metadata_stream, metadata_buf, &size);
+       if (ret < 0) {
+               goto error;
+       }
+
+       do {
+               /*
+                * get_one_metadata_packet returns the number of bytes
+                * received, 0 when we have received everything, a
+                * negative value on error.
+                */
+               ret = get_one_metadata_packet(ctx, metadata_stream);
+       } while (ret > 0);
+
+       if (fclose(metadata_stream->metadata_fp_write))
+               perror("fclose");
+       metadata_stream->metadata_fp_write = NULL;
+
+error:
+       return ret;
+}
+
 /*
  * Get one index for a stream.
  *
@@ -850,7 +919,6 @@ int get_next_index(struct lttng_live_ctx *ctx,
        struct lttng_viewer_get_next_index rq;
        struct lttng_viewer_index rp;
        int ret;
-       uint64_t metadata_len;
        ssize_t ret_len;
 
        cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX);
@@ -915,12 +983,9 @@ retry:
                index->events_discarded = be64toh(rp.events_discarded);
 
                if (rp.flags & LTTNG_VIEWER_FLAG_NEW_METADATA) {
-                       printf_verbose("get_next_index: new metadata needed\n");
-                       ret = get_new_metadata(ctx, viewer_stream,
-                                       &metadata_len);
-                       if (ret < 0) {
+                       ret = append_metadata(ctx, viewer_stream);
+                       if (ret)
                                goto error;
-                       }
                }
                if (rp.flags & LTTNG_VIEWER_FLAG_NEW_STREAM) {
                        ret = ask_new_streams(ctx);
@@ -937,7 +1002,6 @@ retry:
        case LTTNG_VIEWER_INDEX_HUP:
                printf_verbose("get_next_index: stream hung up\n");
                viewer_stream->id = -1ULL;
-               viewer_stream->fd = -1;
                index->offset = EOF;
                ctx->session->stream_count--;
                break;
@@ -1156,14 +1220,15 @@ int del_traces(gpointer key, gpointer value, gpointer user_data)
 static
 void add_traces(gpointer key, gpointer value, gpointer user_data)
 {
-       int i, ret, total_metadata = 0;
-       uint64_t metadata_len;
+       int i, ret;
        struct bt_context *bt_ctx = user_data;
        struct lttng_live_ctf_trace *trace = value;
        struct lttng_live_viewer_stream *stream;
        struct bt_mmap_stream *new_mmap_stream;
        struct bt_mmap_stream_list mmap_list;
        struct lttng_live_ctx *ctx = NULL;
+       struct bt_trace_descriptor *td;
+       struct bt_trace_handle *handle;
 
        /*
         * We don't know how many streams we will receive for a trace, so
@@ -1189,15 +1254,29 @@ void add_traces(gpointer key, gpointer value, gpointer user_data)
                        new_mmap_stream->fd = -1;
                        bt_list_add(&new_mmap_stream->list, &mmap_list.head);
                } else {
+                       char *metadata_buf = NULL;
+
                        /* Get all possible metadata before starting */
-                       do {
-                               ret = get_new_metadata(ctx, stream,
-                                               &metadata_len);
-                               if (ret == 0) {
-                                       total_metadata += metadata_len;
-                               }
-                       } while (ret == 0 || total_metadata == 0);
-                       trace->metadata_fp = fopen(stream->path, "r");
+                       ret = get_new_metadata(ctx, stream, &metadata_buf);
+                       if (ret) {
+                               free(metadata_buf);
+                               goto end_free;
+                       }
+                       if (!stream->metadata_len) {
+                               fprintf(stderr, "[error] empty metadata\n");
+                               ret = -1;
+                               free(metadata_buf);
+                               goto end_free;
+                       }
+
+                       trace->metadata_fp = babeltrace_fmemopen(metadata_buf,
+                                       stream->metadata_len, "rb");
+                       if (!trace->metadata_fp) {
+                               perror("Metadata fmemopen");
+                               ret = -1;
+                               free(metadata_buf);
+                               goto end_free;
+                       }
                }
        }
 
@@ -1212,15 +1291,14 @@ void add_traces(gpointer key, gpointer value, gpointer user_data)
                fprintf(stderr, "[error] Error adding trace\n");
                goto end_free;
        }
+       trace->metadata_stream->metadata_len = 0;
 
+       handle = (struct bt_trace_handle *) g_hash_table_lookup(
+                       bt_ctx->trace_handles,
+                       (gpointer) (unsigned long) ret);
+       td = handle->td;
+       trace->handle = handle;
        if (bt_ctx->current_iterator) {
-               struct bt_trace_descriptor *td;
-               struct bt_trace_handle *handle;
-
-               handle = (struct bt_trace_handle *) g_hash_table_lookup(
-                               bt_ctx->trace_handles,
-                               (gpointer) (unsigned long) ret);
-               td = handle->td;
                bt_iter_add_trace(bt_ctx->current_iterator, td);
        }
 
@@ -1350,35 +1428,7 @@ int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id)
                ctx->session->streams[i].mmap_size = 0;
 
                if (be32toh(stream.metadata_flag)) {
-                       char *path;
-
-                       path = strdup(LTTNG_METADATA_PATH_TEMPLATE);
-                       if (!path) {
-                               perror("strdup");
-                               ret = -1;
-                               goto error;
-                       }
-                       if (!mkdtemp(path)) {
-                               perror("mkdtemp");
-                               free(path);
-                               ret = -1;
-                               goto error;
-                       }
                        ctx->session->streams[i].metadata_flag = 1;
-                       snprintf(ctx->session->streams[i].path,
-                                       sizeof(ctx->session->streams[i].path),
-                                       "%s/%s", path,
-                                       stream.channel_name);
-                       ret = open(ctx->session->streams[i].path,
-                                       O_WRONLY | O_CREAT | O_TRUNC,
-                                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-                       if (ret < 0) {
-                               perror("open");
-                               free(path);
-                               goto error;
-                       }
-                       ctx->session->streams[i].fd = ret;
-                       free(path);
                }
                ret = lttng_live_ctf_trace_assign(&ctx->session->streams[i],
                                be64toh(stream.ctf_trace_id));
This page took 0.031811 seconds and 4 git commands to generate.