Reputation: 123
I'm trying to write a C program for copying content from a source file to a destination file. I want to check for error by checking if the file exists and if the user can read it before attempting to copy it. I use access() from unistd.h.
Here's the context, I have a folder :
.
├── src.txt
├── test
└── test.c
test.c is my program for testing if the file exists and if I can read it.
int main(){
char* path = "src.txt";
fprintf(stderr, "%d\n", access(path, F_OK));
fprintf(stderr, "%d\n", access(path, R_OK));
return 0;
}
In this example, as src.file exists and has permissions 664, the result should be :
1
1
But the actual output is
0
0
Even if I use the absolute path instead of relative path leading to src.txt, I get the same result. What disturbs me is if I try to open the file, it works:
test.c
int main(){
char* path = "src.txt";
fprintf(stderr, "%d\n", access(path, R_OK));
fprintf(stderr, "%d\n", access(path, F_OK));
FILE *f = fopen(path, "r");
if (!f) {
fprintf(stderr, "File couldn't be opened.\n");
} else {
fprintf(stderr, "File successfully opened.\n");
fclose(f);
}
return 0;
}
It gives as output :
0
0
File successfully opened.
I'm sure I'm missing something, but I can't see what it is.
Upvotes: 1
Views: 1690
Reputation: 2585
The access(2)
function returns 0
on success. It returns -1
in case you don't have the requested permissions, or the file does not exist, or the path lookup failed. See the man page. It also sets the errno
variable to the appropriate error code. So the output of 0
, that you are seeing is correct, because you do have read permissions on the said file.
As an aside, most of the system calls return -1 on error (for example read(2)
, open(2)
, write(2)
etc) and set the errno
variable to reflect the exact error which occurred. In order to take the correct action during an error, you need to check the value of the errno
variable.
Upvotes: 4
Reputation: 11921
In this example, as src.file exists and has permissions 664, the result should be : 1 1
? No It should be 0 0
, as from the manual page of access() .
RETURN VALUE On success (all requested permissions granted, or mode is
F_OK
and the file exists), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or mode isF_OK
and the file does not exist, or some other error occurred),-1
is returned, anderrno
is set appropriately
This
fprintf(stderr, "%d\n", access(path, R_OK));
prints 0
as R_OK
test whether the file exists and grants read, write, and execute permissions & as you stated src.txt
exists & its has permission 0664
, hence it prints 0
. And this
fprintf(stderr, "%d\n", access(path, F_OK));
also prints 0
as F_OK
tests for the existence of the file & its true in your case, hence prints 0
.
Upvotes: 3