Linux программирование в примерах
Следующий фрагмент показывает, как создать переменные, представляющие разрешения
и-rw-r--r--(0644 и 0755 соответственно):-rwxr-xr-xmode_t rw_mode, rwx_mode;rw_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; /* 0644 */rwx_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; /* 0755 */Более старый код использовал
,S_IREADиS_IWRITEвместе со сдвигом битов для получения того же результата:S_IEXECmode_t rw_mode, rwx_mode;rw_mode = (S_IREAD|S_IWRITE) | (S_IREAD >> 3) | (S_IREAD >> 6); /* 0644 */rwx_mode = (S_IREAD|S_IWRITE|S_IEXEC) |((S_IREAD|S_IEXEC) >> 3) | ((S_IREAD|S_IEXEC) >> 6); /* 0755 */К сожалению, ни одна из записей не является очень удобной. Современные версии предпочтительнее, поскольку у каждого бита доступа есть собственное имя и меньше вероятность неправильного выполнения побитовых операций.
При изменении прав доступа к файлу для использования доступны биты дополнительных разрешений, показанные в табл. 4.6, но они не должны использоваться при первоначальном создании файла. Возможность включения этих битов широко варьирует между операционными системами. Лучше всего не пробовать; вместо этого следует изменить права доступа к файлу явным образом после его создания. (Изменение прав доступа описано в разделе 5.5.2 «Изменение прав доступа:
иchmod()». Значения этих битов обсуждаются в главе 11 «Права доступа и идентификаторы пользователя и группы».)fchmod()Таблица 4.6. Дополнительные символические имена POSIX для режимов доступа к файлам
Символическое имя Значение Смысл S_ISUID04000 Установить ID пользователя S_ISGID02000 Установить ID группы S_ISVTX01000 Сохранить текст Когда стандартные утилиты создают файлы, они по умолчанию используют права доступа
(или 0666). Поскольку большинство пользователей предпочитают избегать файлов, в которые может записывать кто угодно, каждый процесс имеет при себе umask.-rw-rw-rw-является набором битов допуска, указывающим те биты, которые никогда не должны устанавливаться при создании новых файлов, (umask не используется при изменении прав доступа.) Концептуально осуществляется операцияumaskдействительные_права = (затребованные_права & (~umask));обычно устанавливается с помощью командыumaskвumask, когда вы входите в систему. Из программы С она устанавливается с помощью системного вызова$НОМЕ/.profile.umask()#include <sys/types.h> /* POSIX */#include <sys/stat.h> mode_t umask(mode_t mask);Возвращается старое значение
. Поэтому для определения текущей маски нужно установить новое значение, а затем восстановить старое (или изменить его при необходимости):umaskmode_t mask = umask(0); /* получить текущую маску */(void)umask(mask); /* восстановить ее */Вот пример работы
на уровне оболочки:umask$ <b>umask</b> /* Показать текущую маску */0022$ <b>touch newfile</b> /* Создать файл */$ <b>ls -l newfile</b> /* Показать права доступа нового файла */-rw-r--r-- 1 arnold devel 0 Mar 24 15:43 newfile$ <b>umask 0</b> /* Установить пустую маску */$ <b>touch newfile2</b> /* Создать второй файл */$ <b>ls -l newfile2</b> /* Показать права доступа нового файла */-rw-rw-rw- 1 arnold devel 0 Mar 24 15:44 newfile24.6.2. Создание файлов с помощью
creat()Системный вызов
[49] создает новые файлы. Он объявлен следующим образом:creat()#include <sys/types.h> /* POSIX */#include <sys/stat.h>#include <fcntl.h>int creat(const char *pathname, mode_t mode);Аргумент
представляет права доступа к новому файлу (как обсуждалось в предыдущем разделе). Создается файл с именемmodeданными правами доступа, модифицированными с использованиемpathname.с. Он открыт (только) для чтения, а возвращаемое значение является дескриптором нового файла или -1, если была проблема. В последнем случаеumaskуказывает ошибку. Если файл уже существует, он будет при открытии урезан.errnoВо всех остальных отношениях дескрипторы файлов, возвращаемые
, являются теми же самыми, которые возвращаютсяcreat(); они используются для записи и позиционирования и должны закрываться при помощиopen():close()int fd, count;/* Проверка ошибок для краткости опущена */fd = creat("/some/new/file", 0666);count = write(fd, "some data\n", 10);(void)close(fd);4.6.3. Возвращаясь к open()
Вы можете вспомнить объявление для
:open()int open(const char *pathname, int flags, mode_t mode);Ранее мы сказали, что при открытии файла для простого ввода/вывода мы можем игнорировать аргумент
. Хотя, посмотрев наmode, вы, возможно, догадались, чтоcreat()также может использоваться для создания файлов и что в этом случае используется аргументopen(). Это в самом деле так.mode