$ touch newfile /* Создать файл */
$ ls -l newfile /* Показать права доступа нового файла */
-rw-r--r-- 1 arnold devel 0 Mar 24 15:43 newfile
$ umask 0 /* Установить пустую маску */
$ touch newfile2 /* Создать второй файл */
$ ls -l newfile2 /* Показать права доступа нового файла */
-rw-rw-rw- 1 arnold devel 0 Mar 24 15:44 newfile2
4.6.2. Создание файлов с помощью creat()
Системный вызов creat()
[49] создает новые файлы. Он объявлен следующим образом:
#include
#include
#include
int creat(const char *pathname, mode_t mode);
Аргумент mode
представляет права доступа к новому файлу (как обсуждалось в предыдущем разделе). Создается файл с именем pathname.с
данными правами доступа, модифицированными с использованием umask
. Он открыт (только) для чтения, а возвращаемое значение является дескриптором нового файла или -1, если была проблема. В последнем случае 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
. Это в самом деле так.
Помимо флагов O_RDONLY
, O_WRONLY
и O_RDWR
, при вызове open()
могут добавляться с использованием поразрядного OR
дополнительные флаги. Стандарт POSIX предоставляет ряд этих дополнительных флагов. В табл. 4.7 представлены флаги, которые используются для большинства обычных приложений.
Таблица 4.7. Дополнительные флаги POSIX для open()
Флаг | Значение |
---|---|
O_APPEND | Принудительно осуществляет все записи в конец файла |
O_CREAT | Создает новый файл, если он не существует. |
O_EXCL | При использовании вместе с O_CREAT возвращает ошибку, если файл уже существует |
O_TRUNC | Урезает файл (устанавливает его длину в 0), если он существует. |
Если даны O_APPEND
и O_TRUNC
, можно представить, как оболочка могла бы открывать или создавать файлы, соответствующие операторам >
и >>
. Например:
int fd;
extern char *filename;
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; /* 0666 */
fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, mode); /* для > */
fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, mode); /* для >> */
Обратите внимание, что флаг O_EXCL
здесь не используется, поскольку как для >
, так и для >>
не является ошибкой существование файла. Запомните также, что система применяет к запрошенным правам доступа umask
.
Также легко видеть, что, по крайней мере концептуально, creat()
можно было бы легко написать следующим образом:
int creat(const char *path, mode_t mode) {
return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode);
}
ЗАМЕЧАНИЕ. Если файл открыт с флагом O_APPEND
, все данные будут записаны в конец файла, даже если текущее смещение было восстановлено с помощью lseek()
.
Современные системы предоставляют дополнительные флаги с более специализированным назначением. Они кратко описаны в табл. 4.8.