Reputation: 395
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()
?
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);
}
Upvotes: 5
Views: 22453
Reputation: 20818
In your example, as stated by others, there is no need to reset errno
.
There are, however, a very few functions which return a number and for them, there is no number that can 100% represent an error occurred. In those few cases, resetting errno
is necessary.
One example of such a function is strtol()
. On error it returns -1. If you really want to know whether the user passed "-1"
or whether an error occurred, then you want to do:
errno = 0;
long r = strtol(input, &end, 10);
if(r == -1 && errno != 0)
...handle the error...
In most cases, such functions do spell out the issue in their DESCRIPTION
or RETURN VALUE
manual sections.
As mentioned by others, a function that returns a pointer is likely to return a nullptr
on an error. Then you do not need to reset errno
since you should check errno
only if the function returned nullptr
.
ptr = malloc(123);
if(ptr == nullptr)
...handle error, 'errno' gives you extra hints about error...
Upvotes: 4
Reputation: 45704
No, there is no need to reset errno
before calling the function, because the contract reads:
The
opendir()
andfdopendir()
functions return a pointer to the directory stream. On error,NULL
is returned, anderrno
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.)
Upvotes: 8
Reputation: 598134
errno
is only meaningful after a real error occurs. You have to check for the error condition first, THEN look at errno
, eg:
DIR *dp = opendir(a_dest_path.c_str());
if (dp) {
closedir(dp);
} else {
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 {
// some other error...
}
}
Upvotes: 4