Pythalex
Pythalex

Reputation: 123

access(path, flag) returns 0 even if file exists

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

Answers (2)

Abhinav Upadhyay
Abhinav Upadhyay

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

Achal
Achal

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 is F_OK and the file does not exist, or some other error occurred), -1 is returned, and errno 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

Related Questions