$ 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.