Fix: handling of empty streams
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 4 May 2013 14:32:31 +0000 (10:32 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 4 May 2013 14:32:31 +0000 (10:32 -0400)
Fixes #518

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
formats/ctf/ctf.c

index 6b292a7e567fff53a00abc1b04f91beae8a7cec3..9706f7a3bfcd7eb9b777e5bb8e47036cf397deac 100644 (file)
@@ -682,6 +682,14 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
        off_t off;
        struct packet_index *packet_index;
 
+       switch (whence) {
+       case SEEK_CUR:
+       case SEEK_SET:  /* Fall-through */
+               break;  /* OK */
+       default:
+               assert(0);
+       }
+
        if (pos->prot == PROT_WRITE && pos->content_size_loc)
                *pos->content_size_loc = pos->offset;
 
@@ -721,6 +729,14 @@ void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
                pos->offset = 0;
        } else {
        read_next_packet:
+               if (pos->cur_index >= pos->packet_cycles_index->len) {
+                       pos->offset = EOF;
+                       return;
+               }
+               if (pos->cur_index >= pos->packet_real_index->len) {
+                       pos->offset = EOF;
+                       return;
+               }
                switch (whence) {
                case SEEK_CUR:
                {
@@ -1307,6 +1323,31 @@ error:
        return ret;
 }
 
+static
+int stream_assign_class(struct ctf_trace *td,
+               struct ctf_file_stream *file_stream,
+               uint64_t stream_id)
+{
+       struct ctf_stream_declaration *stream;
+       int ret;
+
+       file_stream->parent.stream_id = stream_id;
+       if (stream_id >= td->streams->len) {
+               fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id);
+               return -EINVAL;
+       }
+       stream = g_ptr_array_index(td->streams, stream_id);
+       if (!stream) {
+               fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id);
+               return -EINVAL;
+       }
+       file_stream->parent.stream_class = stream;
+       ret = create_stream_definitions(td, &file_stream->parent);
+       if (ret)
+               return ret;
+       return 0;
+}
+
 static
 int create_stream_one_packet_index(struct ctf_stream_pos *pos,
                        struct ctf_trace *td,
@@ -1314,7 +1355,6 @@ int create_stream_one_packet_index(struct ctf_stream_pos *pos,
                        size_t filesize)
 {
        struct packet_index packet_index;
-       struct ctf_stream_declaration *stream;
        uint64_t stream_id = 0;
        uint64_t packet_map_len = DEFAULT_HEADER_LEN, tmp_map_len;
        int first_packet = 0;
@@ -1428,18 +1468,7 @@ begin:
                return -EINVAL;
        }
        if (first_packet) {
-               file_stream->parent.stream_id = stream_id;
-               if (stream_id >= td->streams->len) {
-                       fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id);
-                       return -EINVAL;
-               }
-               stream = g_ptr_array_index(td->streams, stream_id);
-               if (!stream) {
-                       fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id);
-                       return -EINVAL;
-               }
-               file_stream->parent.stream_class = stream;
-               ret = create_stream_definitions(td, &file_stream->parent);
+               ret = stream_assign_class(td, file_stream, stream_id);
                if (ret)
                        return ret;
        }
@@ -1580,6 +1609,30 @@ int create_stream_packet_index(struct ctf_trace *td,
        if (ret < 0)
                return ret;
 
+       /* Deal with empty files */
+       if (!filestats.st_size) {
+               if (file_stream->parent.trace_packet_header
+                               || file_stream->parent.stream_packet_context) {
+                       /*
+                        * We expect a trace packet header and/or stream packet
+                        * context. Since a trace needs to have at least one
+                        * packet, empty files are therefore not accepted.
+                        */
+                       fprintf(stderr, "[error] Encountered an empty file, but expecting a trace packet header.\n");
+                       return -EINVAL;
+               } else {
+                       /*
+                        * Without trace packet header nor stream packet
+                        * context, a one-packet trace can indeed be empty. This
+                        * is only valid if there is only one stream class: 0.
+                        */
+                       ret = stream_assign_class(td, file_stream, 0);
+                       if (ret)
+                               return ret;
+                       return 0;
+               }
+       }
+
        for (pos->mmap_offset = 0; pos->mmap_offset < filestats.st_size; ) {
                ret = create_stream_one_packet_index(pos, td, file_stream,
                        filestats.st_size);
This page took 0.028503 seconds and 4 git commands to generate.