Reputation: 1777
I have a simple example:
#include <stdio.h>
#include <errno.h>
int main() {
int result = rename("filea", "doesntexist/fileb");
if (result != 0) {
printf("NOOOO %d\n", errno);
}
return 0;
}
and I want to distinguish between 2 of the possible failures:
but it always returns errno = 2 when either doesn't exist... uhm Any ideas how can I approach this?
Thanks
EDIT: If possible without manually checking if the files exist.
EDIT2: Not checking if the file exists is a stupid constraint ;) so, I've accepted one of the answers already. Thanks!
Upvotes: 0
Views: 1345
Reputation: 96974
I don't know how you're going to check if a file exists without checking if a file exists, but hopefully this function will help you out:
#include <sys/stat.h>
if (!fileExists("foo")) { /* foo does not exist */ }
int fileExists (const char *fn)
{
struct stat buf;
int i = stat(fn, &buf);
if (i == 0)
return 1; /* file found */
return 0;
}
If your goal is to keep the code clean, then just use functions:
int main()
{
if (! renameFiles("fileA", "fileB")) {
fprintf(stderr, "rename failed...\n");
exit EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int renameFiles(const char *source, const char *destination)
{
int result = -1;
if ( (fileExists(source)) && (!fileExists(destination)) )
result = rename(source, destination);
if (result == 0)
return 1; /* rename succeeded */
/*
Either `source` does not exist, or `destination`
already exists, or there is some other error (take
a look at `errno` and handle appropriately)
*/
return 0;
}
You could return custom error codes from renameFiles()
and conditionally handle errors based on which file does or does not exist, or if there is some other problem with the rename()
call.
Upvotes: 1
Reputation: 15954
The ISO C standard does not even require the library function rename
to set errno
in case of error. All that is guaranteed is a non-zero return value on error (7.19.4.2, §3).
So whether this is possible or not depends on your platform (and it is not portable).
E.g. in Linux there is no way to distinguish which of them is missing by just looking at errno
after rename
(according to this man page).
Upvotes: 1
Reputation: 3564
If the errno is always 2 ENOENT "No such file or directory" on your system you are going to HAVE to check for the existence of something. On my system I get errno of 2 if old does not existent or if the directory path of new does not exist.
However there is much more then 2 possible errors. The link http://man.chinaunix.net/unix/susv3/functions/rename.html has 20 distinct errno values specified.
I would suggest that if the rename fails and the errno is 2 then check for the existence of old. If found then the problem is that the directory specified in the new doesn't exist.
Upvotes: 0
Reputation: 16399
Call access()
(unistd.h) first. Or stat()
. And you are probably getting an ENOENT
error when filea does not exist. Some ways you can get an error on fileB:
There are others but they are not very common.
There is no case where you should get an error when fileB is not there. You execute a mv filea fileb (what rename does) and all of the errors for mv apply here. Missing destination file is not one of them.
You should also have
#include <errno.h>
since you reference errno
.
Upvotes: 1