Search code examples
c++linux

Need to clean up errno before calling function then checking errno?


  1. Do we need to reset errno to zero before calling a function? See below code. Now the scenario is a_dest_path is an existing directory. But when I execute the code, it always tries to mkdir but returns error says that the directory can't be created because it exists. In GDB, I check errno before calling opendir() and errno is 2. And it seems errno is not set to zero during calling opendir(). So do I need to reset errno to zero before calling opendir()?

  2. errno may be changed in system() calls, then in my else if branch I check the result from system() but not opendir(). So after opendir(), do I need to assign errno to a variable then check this variable in the if..elseif..else branch?

DIR *dp = opendir(a_dest_path.c_str());
if (errno == ENOENT) {
    string mkdir_comman = "mkdir " + a_dest_path;
    system(mkdir_command.c_str());
} else if (errno == ENOTDIR) {
    printf("Destination %s exists but is not directory\n", a_dest_path.c_str());
    return k_error_not_directory;
} else if (errno == 0) {
    closedir(dp);
}

Solution

  • No, there is no need to reset errno before calling the function, because the contract reads:

    The opendir() and fdopendir() functions return a pointer to the directory stream. On error, NULL is returned, and errno is set appropriately.

    Test the return-value, and only look at errno when you actually have an error!

    (realloc is a rare example of a function where under specific circumstances an error cannot be distinguished from success without looking at errno, though it will clear it if that is necessary for disambiguation.)