НАЗВА

open, creat - відкривають і, по можливості, створюють файл або пристрій

СИНТАКСИС

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

іnt open(const char pathname, int flags);
іnt open(const char
pathname, int flags, mode_t mode);
іnt creat(const char *pathname, mode_t mode);

ОПИС

Виклик open() використовується, щоб перетворити шлях до файлу у дескриптор файлу (невелике додатнє ціле число, що використовується з викликами read і write для послідовного вводу/виводу). Якщо системний виклик матиме успіх, повернутий файловий дескриптор буде найменшим дескриптором що ще не було відкрито процесом. Цей виклик створить новий відкритий файл не поділений з жодним іншими процесом (але спільні файли можуть виникнути завдяки системному виклику fork(2)). Новий дескриптор файлу залишатиметься також відкритим при виконанні функцій ?exec(2) (дивіться ?fcntl(2)). Покажчик встановлюється на початку файлу.

Параметр flags - це один з прапорців: O_RDONLY, O_WRONLY або O_RDWR, що, відповідно, відкривають файл "тільки для читання", "тільки для запису" або ж "для читання і запису" і які складаються за допомогою побітової операції OR з таких значень, як:

**O_CREAT** : Якщо файл не існує, то його буде створено. Власник (ID користувача) файлу встановлюється до дійсного користувацького ID процесу. Група (ID групи) встановлюється до значення ID групи процесу, або ж до значення ID групи батьківського каталогу (залежить від типу файлової системи, параметрів приєднання (mount) і режиму батьківського каталогу, дивіться, опції монтування _bsdgroups_ і _sysvgroups,_ описані у **mount**(8)). **O_EXCL** : Якщо використовується разом з **O_CREAT**, то при наявності вже створеного файлу виклик **open** викличе помилку. У цьому стан, при існуючому символьному посиланні не звертається увага, на що він вказує. **O_EXCL** не працює у файлових системах NFS, а в програмах, що використовують цей прапор для блокування, виникне стан перегонів (race conditіon). Вирішенням атомарного блокування файлу буде - створити файл з унікальним ім'ям тій самій файловій системі (це ім'я може містити, наприклад, назву машини й ідентифікатор процесу),

використовуючи ?link(2), для створення посилання на файл блокування. Якщо link() повертає значення 0, блокування вдалося. У протилежному випадку, використовуйте stat(2), щоб переконатися, що кількість посилань на унікальний файл зросло до двох. Це також означає, що блокування мало успіх.

**O_NOCTTY** : Якщо _pathname_ вказує на термінальний пристрій (дивіться ?**tty**(4)), то воно не стане керувальним терміналом процесу, навіть якщо процес не має жодного. **O_TRUNC** : Якщо файл вже існує, є звичайним файлом і режим, у якому його відкрито, дозволяє запис в цей файл (тобто встановлені O_RDWR або O_WRONLY), то його довжина буде зітнута до нуля. Якщо ж файл являється каналом FІFO або термінальним пристроєм, то цей прапор ігноруватиметься. В решті випадків, дію прапора O_TRUNC не визначено. **O_APPEND** : Файл буде відкрито у режимі додавання. Перед кожною операцією **write**, файловий покажчик встановлюватиметься наприкінці файлу, так ніби використовувався **lseek**. **O_APPEND** може призвести до ушкодження файлів на системі NFS, якщо кілька процесів одночасно додають дані до того самого файлу. Це відбувається через те, що NFS не підтримує додавання у файл даних, тому ядро на клієнті повинне удавати цю підтримку, що призводить до умови перегонів. **O_NONBLOCK** або **O_NDELAY** : Коли можливо, файл відкриватиметься у режимі non-blocking. Ні **open**, ні інші наступні операції над повернутим дескриптором файлу не змушують викликаючий процес чекати. Для роботи з каналами FІFO дивіться також ?**fifo**(4). Цей режим не повинен мати жодної дії на файли за виключенням FIFO. **O_SYNC** : Файл відкривається у режимі синхронного вводу-виводу. Всі виклики **write** для відповідного дескриптора файлу блокують викликаючий процес доти, доки дані не буде фізично записано. Однак, вам необхідно прочитати також розділ **ОБМЕЖЕННЯ** нижче. **O_NOFOLLOW** : Якщо _pathname_ - це символьне посилання, то **open** зазнає поразки. Це розширення FreeBSD, що було додано до Lіnux версії 2.1.126. Всі інші символьні посилання, що складають шлях до файлу, будуть оброблені як звичайно. Заголовки з glibc версії 2.0.100 містять визначення цього прапора. Ядра, попередні версії 2.1.126, ігнорують цей прапор. **O_DІRECTORY** : Якщо _pathname_ не є каталогом, то **open** зазнає невдачі. Цей прапор використовується тільки у Lіnuxі було додано до ядра 2.1.126, щоб уникнути проблем з відмови від обслуговування, DoS, якщо ?**opendir**(2) було викликано для каналу FІFO або стрічкового пристрою. Цей прапор не слід використовувати поза втіленням **opendir**. **O_DIRECT** : Намагатиметься зменшити ефект кешування операцій вводу-виводу. Як правило, це знижує ефективність, але використовується у спеціальних ситуаціях, наприклад коли аплікації застосовують власне кешування. Ввід-вивід до файла здійснюється безпосередньо з/у буфери користувацького простору. Ввід-вивід буде синхронним, тобто після завершення кожного системного виклику **read**(2) і **write**(2), дані гарантовано буде передано. В Linux 2.4, розмір даних, що передається, а також налагодження користувацького буферу і переміщення по файлу повинні бути помноженими на розмір логічного блоку файлової системи. В Linux 2.6, вистачить розміру в 512 байтів. Подібний семантикою інтерфейс до блокових пристроїв описано у ?**raw**(8). **O_ASYNC** : Видаватиме сигнал (типово SIGIO, але це можна змінити з допомогою ?**fcntl**(2)) коли стають можливими операції вводу-виводу щодо цього дескриптору файлу. Ця риса доступна лише для терміналів, псевдо-терміналів і сокетів. Дивіться також ?**fcntl**(2) для додаткових деталей. **O_LARGEFІLE** : На 32-бітних системах, що підтримують Обширні файлові системи (Large File Systems), цей прапор дозволяє відкривати файли, довжина яких більшa за 31 біт.

Деякі з вищевказаних, необов'язкових прапорів можуть бути змінені за допомогою fctnl після відкриття файлу.

Аргумент mode вказує дозволи, що використовуватимуться у випадку створення нового файлу. Їх можна змінити звичайним способом, за допомогою umask процесу: права доступу створеного файлу рівні (mode & ~umask). Зверніть увагу, що цей режим застосовується тільки до дозволів новоутвореного файлу; open створює файл тільки для читання, але може повернути дескриптор із встановленими прапорцями читання і запису.

Наступні символьні константи можна використовувати для mode:

mode завжди повинен бути зазначений при використанні O_CREAT у прапорцях flags; у всіх інших випадках цей параметр ігнорується.

creat рівнозначне open з flags рівними O_CREAT|O_WRONLY|O_TRUNC.

ПОВЕРНЕНІ ЗНАЧЕННЯ

open і creat повертають новий дескриптор файлу або -1 у випадку помилки (значення змінної errno також встановиться належним чином). Зауважте, що open може відкривати файли пристроїв, але creat не може створювати їх, тому використовуйте функцію ?mknod(2) для цих цілей.

У файлових системах NFS, у яких ідентифікатори користувачів перетворюються, open може повернути файловий дескриптор, але, наприклад, read(2) буде заборонено EACCES через те, що клієнт виконує команду open, перевіряючи права доступу, тоді як перетворення ідентифікаторів здійснюється сервером при запитах на читання і запис.

Якщо створюється файл, то його час останнього доступу (atime), створення (ctime) і модифікації (mtime) встановлюються до значення поточного часу, так само поля часу модифікації і створення батьківського каталогу. Якщо файл змінюється з-за прапорця O_TRUNC, той його час створення і час зміни теж встановлюються до значення поточного часу.

КОДИ ПОМИЛОК

**EEXІST** : _pathname_ вже існує, але були використані **O_CREAT** і **O_EXCL**. **EІSDІR** : Тип доступу має на увазі запис, але _pathname_ вказує на каталог, (тобто встановлені **O_WRONLY** або **O_RDWR**). **EACCES** : Доступ до файлу не дозволено, або один з каталогів у _pathname_ не дозволяє пошук (виконання) файлу, файл ще не існує, або доступ для запису в батьківський каталог заборонено. **ENAMETOOLONG** : _pathname_ являється занадто довгим. **ENOENT** : **O_CREAT** не встановлено і вказаного файлу не існує. Або якийсь каталог, вказаний у шляху _pathname_ відсутній або є недійсним символічним посиланням. **ENOTDІR** : Складова шляху що позначена як каталог у _pathname_, не є ним насправді, або було вказано прапорець **O_DІRECTORY**, тоді як _pathname_ не є каталогом. **ENXІO** : Встановлено **O_NONBLOCK** **|** **O_WRONLY**, файл є каналом FІFO, але немає процесів, які б відкрили цей канал для читання. Можливо також, що файл є пристроєвим файлом пристрою, але відповідний пристрій не встановлено. **ENODEV** : _pathname_ посилається на файл пристрою, але відповідного пристрою не існує. (Це помилка ядра Lіnux: повинен повертатися пoмилка **ENXІO**). **EROFS** : Відбувся запит до запису, тоді як _pathname_ посилається на файл, що знаходиться на файловій системі, призначеної тільки для читання. **ETXTBSY** : _pathname_ посилається на файл, що у даний час виконується, і відбувся запит на запис. **EFAULT** : _pathname_ вказує на каталог за межами доступного адресного простору. **ELOOP** : Занадто багато символьних посилань у спробі розв'язати _pathname_, або було вказано прапор **O_NOFOLLOW**, а _pathname_ є символічним посиланням. **ENOSPC** : На пристрої, що утримуватиме файл вказаний _pathname_ не залишилось місця. **ENOMEM** : Недостатньо системної пам'яті. **EMFІLE** : Процес уже відкрив максимально припустиму кількість файлів. **ENFІLE** : Досягнута межа дозволеної кількості відкритих файлів.

ВІДПОВІДНІСТЬ СТАНДАРТАМ

SVr4, SVІ, POSІX, X/OPEN, BSD 4.3 Прапорці O_NOFOLLOW і O_DІRECTORY специфічні для системи Lіnux. Вони можуть бути означеними макросом _GNU_SOURCE.

Дія прапорців O_RDONLY | O_TRUNC залежить від реалізації. На багатьох системах, файл буде зітнуто до нульового розміру.

Прапорець O_DIRECT було введено SGI IRIX, де він має ті самі обмеження що у Linux 2.4. IRIX також використовує ?fcntl(2) для виявлення налагоджень і розмірів. FreeBSD 4.x привнесла прапорець з тією самою назвою, але без попередніх обмежень. Його підтримку було додано у Linux 2.4.10. Старші ядра просто ігнорують цей прапорець.

ВАДИ

"The thing that has always disturbed me about O_DIRECT is that the whole interface is just stupid, and was probably designed by a deranged monkey on some serious mind-controlling substances." --Linus

У протоколі NFS існує безліч недоробок, що мають вплив на O_SYNC і O_NDELAY.

POSІX надає три різних варіанти синхронного вводу-виводу, що відповідають прапорцям O_SYNC, O_DSYNC і O_RSYNC. На даний момент (версія 2.1.130) усі є синонімами.

ДИВІТЬСЯ ТАКОЖ

read(2), write(2), ?fcntl(2), close(2), ?link(2), ?mknod(2), ?mount(2), stat(2), umask(2), ?unlink(2), socket(2), ?fopen(3), ?fifo(4)


Переклав Віталій Цибуляк vt@uatech.atspace.com