Neater way to handle errors from multiple fread calls

Viewed 153

I have the following method in C to load a binary file, it seems rather long and tedious having to check the error value from each and every fread call, is there a neater way to handle this?

I'm aware that some of the calls could be reduced by reading in a struct in one go, but due to how C can add padding bytes in between struct members, I'd prefer to avoid this.

some_type_t *load_something(FILE *file) {
    some_type_t *something = (some_type_t *)malloc(sizeof(some_type_t));
    if (something == NULL) {
        return NULL;
    }

    if (fread(&something->field1, sizeof(something->field1), 1, file) == 0) {
        free(something);
        return NULL;
    }
    if (fread(&something->field2, sizeof(something->field2), 1, file) == 0) {
        free(something);
        return NULL;
    }
    if (fread(&something->field3, sizeof(something->field3), 1, file) == 0) {
        free(something);
        return NULL;
    }

    uint16_t some_var1, some_var2, some_var3;

    some_other_type_t *something_else1 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
    if (fread(&some_var1, sizeof(some_var1), 1, file) == 0) {
        free(something);
        free(something_else1);
        return NULL;
    }

    some_other_type_t *something_else2 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
    if (fread(&some_var2, sizeof(some_var2), 1, file) == 0) {
        free(something);
        free(something_else1);
        free(something_else2);
        return NULL;
    }

    some_other_type_t *something_else3 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
    if (fread(&some_var3, sizeof(some_var3), 1, file) == 0) {
        free(something);
        free(something_else1);
        free(something_else2);
        free(something_else3);
        return NULL;
    }
    // Do something with the vars and allocated something elses.
    // ...

    return something;
}
4 Answers
Related