8.2. Функция access(): проверка прав доступа к файлу

8.2. Функция access(): проверка прав доступа к файлу

Функция access() определяет, имеет ли вызывающий ее процесс право доступа к заданному файлу. Функция способна проверить любую комбинацию привилегий чтения, записи и выполнения, а также факт существования файла.

Функция access() принимает два аргумента: путь к проверяемому файлу и битовое объединение флагов R_OK, W_OK и X_OK, соответствующих правам чтения, записи и выполнения. При наличии у процесса всех необходимых привилегий функция возвращает 0. Если файл существует, а нужные привилегии на доступ к нему у процесса отсутствуют, возвращается -1 и в переменную errno записывается код ошибки EACCES (или EROFS, если проверяется право записи в файл, который расположен в файловой системе, смонтированной только для чтения).

Если второй аргумент равен F_OK, функция access() проверяет лишь факт существования файла. В случае обнаружения файла возвращается 0, иначе — -1 (в переменную errno помещается также код ошибки ENOENT). Когда один из каталогов на пути к файлу недоступен, в переменную errno будет помещён код EACCES.

Программа, показанная в листинге 8.1, с помощью функции access() проверяет существование файла и определяет, разрешен ли к нему доступ на чтение/запись. Имя файла задается в командной строке.

Листинг 8.1. (check-access.c) Проверка прав доступа к файлу

#include <errno.h>

#include <stdio.h>

#include <unistd.h>

int main(int argc, char* argv[]) {

 char* path = argv[1];

 int rval;

 /* Проверка существования файла. */

 rval = access(path, F_OK);

 if (rval == 0)

  printf("%s exists ", path);

 else {

  if (errno == ENOENT)

   printf("%s does not exist ", path);

  else if (errno == EACCES)

   printf("%s is not accessible ", path);

  return 0;

 }

 /* Проверка права доступа. */

 rval = access(path, R_OK);

 if (rval == 0)

  printf("%s is readable ", path);

 else

  printf("%s is not readable (access denied) ", path);

 /* проверка права записи. */

 rval = access(path, W_OK);

 if (rval == 0)

  printf("%s is writable ", path);

 else if (errno == EACCES)

  printf("%s is not writable (access denied) ", path);

 else if (errno == EROFS)

  printf("%s is not writable (read-only filesystem) ",

   path);

 return 0;

}

Вот как, к примеру, проверить права доступа к файлу README, расположенному на компакт-диске:

% ./check-access /mnt/cdrom/README

/mnt/cdrom/README exists

/mnt/cdrom/README is readable

/mnt/cdrom/README is not writable (read-only filesystem)