+ assert(ret_len == sizeof(rp));
+
+ switch(be32toh(rp.status)) {
+ case LTTNG_VIEWER_NEW_STREAMS_OK:
+ break;
+ case LTTNG_VIEWER_NEW_STREAMS_NO_NEW:
+ ret = 0;
+ goto end;
+ case LTTNG_VIEWER_NEW_STREAMS_HUP:
+ ret = -LTTNG_VIEWER_NEW_STREAMS_HUP;
+ goto end;
+ case LTTNG_VIEWER_NEW_STREAMS_ERR:
+ fprintf(stderr, "[error] get_new_streams error\n");
+ ret = -1;
+ goto end;
+ default:
+ fprintf(stderr, "[error] Unknown return code %u\n",
+ be32toh(rp.status));
+ ret = -1;
+ goto end;
+ }
+
+ ctx->session->stream_count += be32toh(rp.streams_count);
+ /*
+ * When the session is created but not started, we do an active wait
+ * until it starts. It allows the viewer to start processing the trace
+ * as soon as the session starts.
+ */
+ if (ctx->session->stream_count == 0) {
+ ret = 0;
+ goto end;
+ }
+ printf_verbose("Waiting for %" PRIu64 " streams:\n",
+ ctx->session->stream_count);
+ ctx->session->streams = g_new0(struct lttng_live_viewer_stream,
+ ctx->session->stream_count);
+ for (i = 0; i < be32toh(rp.streams_count); i++) {
+ do {
+ ret_len = recv(ctx->control_sock, &stream, sizeof(stream), 0);
+ } while (ret_len < 0 && errno == EINTR);
+ if (ret_len < 0) {
+ fprintf(stderr, "[error] Error receiving stream\n");
+ ret = ret_len;
+ goto error;
+ }
+ assert(ret_len == sizeof(stream));
+ stream.path_name[LTTNG_VIEWER_PATH_MAX - 1] = '\0';
+ stream.channel_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0';
+
+ printf_verbose(" stream %" PRIu64 " : %s/%s\n",
+ be64toh(stream.id), stream.path_name,
+ stream.channel_name);
+ ctx->session->streams[i].id = be64toh(stream.id);
+ ctx->session->streams[i].session = ctx->session;
+
+ ctx->session->streams[i].first_read = 1;
+ 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));
+ if (ret < 0) {
+ goto error;
+ }
+
+ }