]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - mp4.c
mp4: Implement error checking for the write path.
[paraslash.git] / mp4.c
diff --git a/mp4.c b/mp4.c
index 398a3dcf888472704429220b2d53549b0f157fbc..fc8c41b4af919358350812cae68033611c5d33c4 100644 (file)
--- a/mp4.c
+++ b/mp4.c
@@ -970,28 +970,27 @@ static void *modify_moov(struct mp4 *f, uint32_t *out_size)
        return out_buffer;
 }
 
-static int32_t write_data(struct mp4 *f, void *data, uint32_t size)
+static int write_data(struct mp4 *f, void *data, size_t size)
 {
-       int32_t result = 1;
-
-       result = f->cb->write(f->cb->user_data, data, size);
-
-       f->current_position += size;
-
-       return result;
-}
-
-static int32_t write_int32(struct mp4 *f, uint32_t data)
-{
-       int8_t temp[4];
-       write_u32_be(temp, data);
-       return write_data(f, temp, sizeof(temp));
+       while (size > 0) {
+               ssize_t ret = f->cb->write(f->cb->user_data, data, size);
+               if (ret < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       return -ERRNO_TO_PARA_ERROR(errno);
+               }
+               f->current_position += ret;
+               size -= ret;
+       }
+       return 1;
 }
 
-int32_t mp4_meta_update(struct mp4 *f)
+int mp4_meta_update(struct mp4 *f)
 {
        void *new_moov_data;
        uint32_t new_moov_size;
+       uint8_t buf[8] = "----moov";
+       int ret;
 
        set_position(f, 0);
        new_moov_data = modify_moov(f, &new_moov_size);
@@ -1001,16 +1000,24 @@ int32_t mp4_meta_update(struct mp4 *f)
        }
        if (f->last_atom != ATOM_MOOV) {
                set_position(f, f->moov_offset + 4);
-               write_data(f, "free", 4); /* rename old moov to free */
+               ret = write_data(f, "free", 4); /* rename old moov to free */
+               if (ret < 0)
+                       goto free_moov;
                set_position(f, f->file_size); /* write new moov atom at EOF */
        } else /* overwrite old moov atom */
                set_position(f, f->moov_offset);
-       write_int32(f, new_moov_size + 8);
-       write_data(f, "moov", 4);
-       write_data(f, new_moov_data, new_moov_size);
-       free(new_moov_data);
+       write_u32_be(buf, new_moov_size + 8);
+       ret = write_data(f, buf, sizeof(buf));
+       if (ret < 0)
+               goto free_moov;
+       ret = write_data(f, new_moov_data, new_moov_size);
+       if (ret < 0)
+               goto free_moov;
        f->cb->truncate(f->cb->user_data);
-       return 1;
+       ret = 1;
+free_moov:
+       free(new_moov_data);
+       return ret;
 }
 
 static char *meta_find_by_name(const struct mp4 *f, const char *item)