69: /* Если statFile сбоит, rc будет содержать не ноль.*/
70: rc |= statFile(argv[i]);
71:
72: /* это печатает пробел между позициями,
73: но не за последней */
74: if ((argc - i) > 1) printf ("\n");
75: }
76:
77: return rc;
78: }
11.3.3. Простое определение прав доступа
Хотя режим файла представляет всю информацию, которая может понадобиться программе, для определения того, имеет ли она доступ к файлу, тестирование набора прав — дело хитрое и чреватое ошибкам. Поскольку ядро ухе включает в себя код для проверки прав доступа, предусмотрен простой системный вызов, который позволяет программам определять, могут ли они получить доступ к файлу определенным образом.
#include <unistd.h>
int access(const char *pathname, int mode);
mode
— это маска, которая содержит одно или более перечисленных ниже значений.
F_OK
Файл существует. Это требует прав на выполнение по всем каталогам, составляющим путь, поэтому может закончиться сбоем, даже если файл существует.
R_OK
Процесс может читать файл.
W_OK
Процесс может писать файл.
X_OK
Процесс может исполнять файл (или искать в каталоге).
access
возвращает 0, если указанный режим доступа разрешен, в противном случае возвращает ошибку
EACCESS
.
11.3.4. Изменение прав доступа к файлу
Права доступа и модификаторы прав доступа к файлу изменяются с помощью системного вызова
chmod
.
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);
Хотя
chmod
позволяет указать путь, помните, что права доступа к файлу определяет inode, а не имя файла. Если у файла есть множество жестких ссылок, то изменение прав доступа по одному из имен файла изменяет права доступа к нему везде, где он встречается в файловой системе. Параметр
mode
может быть любой комбинацией прав доступа и модификаторов прав доступа, объединенных по логическому "И". Хотя это достаточно нормально — специфицировать по несколько этих значений за раз, общей практикой для программ является указание новых прав доступа
непосредственно в восьмеричном виде. Только пользователь root и владелец файла могут изменять права доступа к файлу — все остальные, кто попытается это сделать, получат ошибку
EPERM
.
11.3.5. Смена владельца и группы файла
Точно так же, как права доступа, информация о группе и владельце файла хранится в inode, поэтому все жесткие ссылки на файл имеют одинакового владельца и группу. Похожий системный вызов используется для смены владельца и группы файла.
#include <unistd.h>
int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
Параметры
owner
и
group
указывают нового владельца и группу для файла. Если любой из них равен
– 1
, соответствующее значение не изменяется. Только пользователь root имеет право сменить владельца файла. Когда владелец файла меняется или файл записывается, то бит setuid для этого файла всегда очищается из соображений безопасности. Как root, так и владелец файла могут менять группу, которая владеет файлом, но при условии, что владелец сам является членом этой группы. Если у файла установлен бит выполнения для группы, то бит setgid очищается из тех же соображений безопасности. Если же бит выполнения для группы не установлен, то у файла включена принудительная блокировка и режим предохраняется.
11.3.6. Изменение временных меток файла
Владелец файла может изменять mtime и atime файла на любое желаемое значение. Это делает такие метки бесполезными для целей аудита, но позволяет инструментам архивирования вроде
tar
и
cpio
сбрасывать временные метки файлов в то значение, когда они были архивированы. Метка ctime изменяется, когда обновляются mtime и atime, поэтому
tar
и
cpio
не могут восстановить их.
Существуют два способа изменения этих меток:
utime
и
utimes
.
utime
появилась в System V, после чего была адаптирована POSIX, в то время как
utimes
пришла из BSD. Обе функции эквивалентны; они отличаются только способом, каким указываются новые временные метки.
#include <utime.h>
int utime(const char *pathname, struct utimbuf *buf);
#include <sys/time.h>
int utimes(const char *pathname, struct timeval *tvp);