In C, what are some of the most common options to validate parameters and handle errors?

Viewed 84

Say I had the following code:

int calcTotalLinesFromFile(FILE *source_file) {
    /* Calculate number of lines in source_file and return */
}

int addToFile(char *name_of_file, char *file_content, int line_num) {
    FILE *temporary_file;
    FILE *source_file;
    int temp = 1;
    int ch;

    if (access(file_name, F_OK) != 0) {
        fprintf(stderr, "Cannot add content to file %s: File does not exist.\n", name_of_file);
        return errno;
    }

    source_file = fopen(name_of_file, "r");
    if (source_file == NULL) {
        perror("Cannot add content to file");
        return errno;
    }

    int total_lines = calcTotalLinesFromFile(source_file);
    if (line_num > total_lines) {
        fprintf(stderr, "Entered line number exceeds maximum file line.\n");
        return -1;
    } else if (line_num < 1) {
        fprintf(stderr, "Entered line number must be greater than zero.\n");
        return -1;
    }

    temporary_file = fopen("tempfile.tmp", "w");
    if (temporary_file == NULL) {
        perror("Could not write content to file");
        return errno;
    }
    
    /* Add content to file */
    /*       ...           */

    fclose(source_file);
    fclose(temporary_file);

    int successful_delete = remove(source_file_name);
    if (successful_delete != 0) {
        perror("Could not delete source file");
        remove("tempfile.tmp");  /* Clean up after failure */
        return errno;
    }

    int successful_rename = rename("tempfile.tmp", source_file_name);
    if (successful_rename != 0) {
        perror("Could not rename new file");
        remove("tempfile.tmp") /* Clean up after failure */
        return errno
    }

    return 0;
}

Here I perform error checks on nearly all functions that could fail so that I can keep the user informed about what exactly is going wrong and to prevent them from inputting data that would throw more errors in the program. My only problem is that it makes my method much much longer than normal, and the method definitely cannot fit on my monitor without having to scroll down. My questions are as follows:

  1. Are there other options for error handling in C?
  2. Am I possibly checking for errors too often?
  3. Is it also common to have the caller validate the parameters before passing them to the method?

Edit: fixed syntax errors.

1 Answers

First, it is not common practice to return errno. Typically functions return -1 and ask the caller to check errno. You especially shouldn't mix the two practices (you return -1 when fprintf fails but you return errno everywhere else). As for other options, one common idiom is using goto for cleanup. (See Valid use of goto for error management in C?)

You can never check errors too often. Nearly every call to the OS can fail somehow, so you should always check. Even fclose can fail.

Related