The access system call determines whether the calling process has access permission to a file. It can check any combination of read, write, and execute permission, and it can also check for a file's existence.
The access call takes two arguments. The first is the path to the file to check. The second is a bitwise or of R_OK, W_OK, and X_OK, corresponding to read, write, and execute permission. The return value is 0 if the process has all the specified permissions. If the file exists but the calling process does not have the specified permissions, access returns -1 and sets errno to EACCES (or EROFS, if write permission was requested for a file on a read-only file system).
If the second argument is F_OK, access simply checks for the file's existence. If the file exists, the return value is 0; if not, the return value is -1 and errno is set to ENOENT. Note that errno may instead be set to EACCES if a directory in the file path is inaccessible.
The program shown in Listing 8.1 uses access to check for a file's existence and to determine read and write permissions. Specify the name of the file to check on the command line.
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
int main (int argc, char* argv[])
{
char* path = argv[1];
int rval;
/* Check file existence. */
rval = access (path, F_OK);
if (rval == 0)
printf ("%s exists\n", path);
else {
if (errno == ENOENT)
printf ("%s does not exist\n", path);
else if (errno == EACCES)
printf ("%s is not accessible\n", path);
return 0;
}
/* Check read access. */
rval = access (path, R_OK);
if (rval == 0)
printf ("%s is readable\n", path);
else
printf ("%s is not readable (access denied)\n", path);
/* Check write access. */
rval = access (path, W_OK);
if (rval == 0)
printf ("%s is writable\n", path);
else if (errno == EACCES)
printf ("%s is not writable (access denied)\n", path);
else if (errno == EROFS)
printf ("%s is not writable (read-only filesystem)\n", path);
return 0;
}
For example, to check access permissions for a file named README on a CD-ROM, invoke it like this:
% ./check-access /mnt/cdrom/README
/mnt/cdrom/README exists
/mnt/cdrom/README is readable
/mnt/cdrom/README is not writable (read-only filesystem)