Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PR_СП_лекции_укр.doc
Скачиваний:
6
Добавлен:
22.04.2019
Размер:
697.34 Кб
Скачать

2.1.4 Системні виклики роботи з файлами

Системні функції роботи з файлами класифікуються на декілька категорій

  • уведення-виведення (open, read, write, close)

  • створення файлу

  • зміна поточній директорії

  • монтаж файлової системи

  • виконання файлу

  • отримання статусу файлу

  • зміна статусу файлу

  • модифікація імені файлу (link/unlink).

Системних викликів, безпосередньо доступних користувачеві, 19 і їх можна розбити на 7 категорій:

  1. виклики, що повертають файлові дескриптори (покажчики на INODE) з можливою їх модифікацією:

OPEN, CLOSE, CREAT, PIPE, DUP.

  1. виклики, що привласнюють або звільняючі INODE's:

CREAT, LINK, UNLINK.

  1. виклики введення/виводу в процес:

READ, WRITE, LSEEK.

  1. виклики для установки або модифікації атрибутів

файлів:

CHOWN, CHMOD, STAT, FSTAT.

  1. виклики для зміни файлової системи:

MOUNT, UNMOUNT.

  1. виклики, що дозволяють процесу модифікувати шлях у

файловій системі:

CHDIR, CHROOT.

  1. виклики, що використовують алгоритм namei(), щоб аналізувати маршрут:

OPEN, MKNOD, CHROOT, CHMOD, MOUNT, CREAT, CHDIR, CHOWN, STAT, UMOUNT.

Системні функції забезпечуються системними викликами.

Функції для роботи з потоками починаються на букву f, що стоїть перед ім'ям аналогічною функцією для дескрипторів:

fopen - open

fclose - close

fseek - lseek і т.п.

2.2 Створення та відкриття файлів

2.2.1 Системний виклик open

Функція відкриття файлу створює новий потік і встановлює з'єднання між потоком і файлом, можливо включаючи створення нового файлу.

Функції creat і open визначені в заголовному файлі <fcntl.h>, а функція close – у файлі <unistd.h>.

open — відкриває або створює файл

Виклик системної функції open (відкрити файл) - це перший крок, який повинен зробити процес, щоб звернутися до даним у файлі. Синтаксис виклику функції open:

fd = open(pathname, flags, modes);

де pathname - ім'я файлу

flags указує режим відкриття (наприклад, для читання або запису)

а modes містить права доступу до файлу у випадку, якщо файл створюється.

open повертає ціле число, відповідне дескриптору файлу і використовуване іншими операціями над файлами.

Виклик open може завершитися з помилкою з багатьох причин. В цьому випадку open() повертає -1 (в цьому випадку errno встановлюється належним чином). Найчастіше зустрічаються наступні: файл не існує (errno==ENOENT), або не дозволений відповідний доступ до цього файлу (errno==EACCES);

Значення параметра flags

Параметр flags може приймати одне з наступних трьох значень:

  • O_RDONLY – якщо над файлом надалі здійснюватимуться тільки операції читання;

  • O_WRONLY – якщо над файлом надалі здійснюватимуться тільки операції запису;

  • O_RDWR – якщо над файлом здійснюватимуться і операції читання, і операції запису.

Кожне з цих значень може бути скомбіноване за допомогою операції "побітове або ( | )" з одним або декількома прапорами:

  • O_CREAT – якщо файлу з вказаним ім'ям не існує, він повинен бути створений;

  • O_EXCL – застосовується спільно з прапором O_CREAT. У разі, коли ми вимагаємо, щоб файл на диску був відсутній і був створений у момент відкриття, При існуванні файлу з вказаним ім'ям, відкриття файлу не проводиться і констатується помилкова ситуація. Використовується для запобігання ненавмисному знищенню вже існуючого файлу.

  • O_NDELAY – забороняє переклад процесу в стан очікування при виконанні операції відкриття і будь-яких подальших операціях над цим файлом;

  • O_APPEND – при відкритті файлу і перед виконанням кожної операції запису (якщо вона, звичайно, дозволена) покажчик поточної позиції у файлі встановлюється на кінець файлу;

  • O_TRUNC – якщо файл існує, зменшити його розмір 0, із збереженням існуючих атрибутів файлу, окрім, мабуть, часів останнього доступу до файлу і його останньої модифікації.

Використання прапора O_TRUNC приводить до знищення всіх даних у файлі, тому його допустимо указувати тільки при відкритті існуючого файлу і за умови, що процес має право на запис у файл, що відкривається. З тієї ж причини, прапор O_TRUNC не може використовуватися спільно з прапором O_RDONLY. Щоб створити новий файл (з прапором O_CREAT), процес повинен мати право на запис в каталог, оскільки посилання на файл буде записано у файл каталога. При відкритті існуючого файлу права доступу до каталога не мають значення. В цьому випадку в розрахунок приймаються тільки права доступу до файлу.

Слід також відмітити, що процес повинен володіти правом на пошук (виконання) в проміжних каталогах. Прапор O_TRUNC не повинен використовуватися без O_CREAT, якщо передбачається створення нового файлу. Сам по собі він означає наступне: «якщо файл існує — видалити з нього всі дані, якщо файл не існує — завершитися з ознакою помилки».

Крім того, в деяких версіях операційної системи UNIX можуть застосовуватися додаткові значення прапорів:

  • O_SYNC – будь-яка операція запису у файл блокуватиметься (тобто процес буде переведений в стан очікування) до тих пір, поки записана інформація не буде фізично поміщена на соответсвующий рівень hardware, що пролягає нижче;

  • O_NOCTTY – якщо ім'я файлу відноситься до термінального пристрою, воно не стає терміналом процесу, що управляє, навіть якщо до цього процес не мав терміналу, що управляє.

У разі відкриття існуючого файлу, аргумент MODE ігнорується і в текстах програм, як правило, взагалі опускається. Таким чином, функція open викликається всього з двома аргументами, наприклад:

Якщо файл із заданим ім'ям існує на диску, і права доступу до нього для користувача, від імені якого працює поточний процес, не противоречат запитаному набору операцій, то операційна система сканує таблицю відкритих файлів від її початку до кінця у пошуках першого вільного елементу, заповнює його і повертає індекс цього елементу як файловий дескриптор відкритого файлу. Якщо файлу на диску немає, не вистачає прав або відсутнє вільне місце в таблиці відкритих файлів, то констатується виникнення помилки.

Створення файлу за допомогою сисвызова open()

У разі, коли ми допускаємо, що файл на диску може бути відсутнім, і хочемо, щоб він був створений, прапор для набору операцій повинен використовуватися в комбінації з прапором O_CREAT. Якщо файл існує, то все відбувається за розглянутим вище сценарієм. Якщо файл з вказаним ім'ям не існує, виклик open створить його. Крім того, необхідно визначити параметр mode.

Параметр mode встановлює атрибути прав доступу різних категорій користувачів до нового файлу при його створенні. Він обов'язковий, якщо серед заданих прапорів присутній прапор O_CREAT, і може бути опущений інакше. Цей параметр задається як сума наступних вісімкових значень:

0400 – дозволено читання для користувача, що створив файл;

0200 – дозволений запис для користувача, що створив файл;

0100 – дозволено виконання для користувача, що створив файл;

0040 – дозволено читання для групи користувача, що створив

файл;

0020 – дозволений запис для групи користувача, що створив

файл;

0010 – дозволено виконання для групи користувача, що створив

файл;

0004 – дозволено читання для решти всіх користувачів;

0002 – дозволений запис для решти всіх користувачів;

0001 – дозволено виконання для решти всіх користувачів.

У стандарті POSIX Ці коди мають ще і мнемонічні імена (використовувані у виклику stat):

Принцип їх іменування слідує шаблону S_Ipwww, де p визначає режим доступу (R, w або X), а www — кому видається право на цей режим доступу (USR, GRP або OTH).

Наприклад, для вісімкового числа 755 можна записати:

S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH

Існують окремі ідентифікатори для USR, GRP і OTH, які описують повні права доступу. Іменування цих ідентифікаторів слідує формі S_IRWXw. Тут символ w визначає, кому видається повне право доступу до файлу (від англ, «whom» — «кому») — U, G або О. Таким образом, попередній приклад може бути записаний в наступному вигляді:

S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH

Використання ідентифікаторів дає розробникам ОС свободу вибору порядку проходження битий, що описують права доступу до файлу.

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

При створенні файлу реально встановлювані права доступу виходять із стандартної комбінації параметра mode і маски створення файлів поточного процесу umask, а саме – вони дорівнюють

mode & umask.

Маска зазвичай встановлюється під час реєстрації користувача в системі (командою umask) або системним викликом umask. Фраза «логічне множення на логічне доповнення» означає: якщо якийсь біт маски встановлений, то відповідний йому битий в остаточному наборі прав доступу скидається.

Так, маска 002 приведе до того, що битий S_IWOTH (право на запис для всіх останніх) буде скинутий, навіть якщо в системний виклик open буде переданий прапор S_IWOTH.

Що відбудеться, якщо ви створити файл з прапором O_WRONLY або O_RDWR, але при цьому не дати йому права на запис? Оскільки файл був тільки що створений, він поки що доступний для запису. Проте, коли наступного разу ви спробуєте відкрити його, всі накладені вами обмеження набудуть чинності.

Приклади

#include <fcntl.h>

#define TMPFILE "/tmp/tmpfile"

main (int argc, char ** argv)

{

char account[] = "account";

int logfd, acctfd, fd, fdin, fdout;

char *file;

/* Файл account, що знаходиться в поточному каталозі, відкривається для читання. */

acctfd = open(account, O_RDONLY);

/* Файл, на ймення який указує file, відкривається для запису.

Якщо файл не існує, він створюється з маскою прав доступу 0600 (не рахуючи umask-установок). Якщо файл існує, він буде усічений до нульового розміру.*/

file = TMPFILE;

fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0600);

/* Файл з абсолютним путнім ім'ям ("/sys/log") відкривається для записи. Всі записи проводяться в кінець файлу. Якщо файл не існує, він створюється з маскою прав доступу 0600.*/

logfd = open("/sys/log", O_WRONLY | O_APPEND | O_CREAT, 0600);

/* Файл, ім'я якого було передане main як перший аргумент відкривається на читання/запис. */

fdin = open(argv[1], O_RDWR);

/* Файл відкривається на запис. Якщо він не існує, він створюється. Інакше виклик буде завершений неуспіх. Відмітьте, що виклик open(2) перевіряється в тілі оператора if. Програма винна зробити якісь дії у разі неуспіху. */

if ((fdout = open(TMPFILE, O_WRONLY | O_CREAT | O_EXCL

0666)) == -1)

perror(TMPFILE);

}

Відповідність аргументів fopen і open:

rwmode irwmode

------------------------

"r" O_RDONLY

"w" O_WRONLY|O_CREAT |O_TRUNC

"r+" O_RDWR

"w+" O_RDWR |O_CREAT |O_TRUNC

"a" O_WRONLY|O_CREAT |O_APPEND

"a+" O_RDWR |O_CREAT |O_APPEND

Приклад програми

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

int main()

{

extern int errno;

int fd;

if( fd = open( "nosuchfile", O_RDONLY )== -1 )

{

fprintf( stderr, "Error %d\n", errno );

perror( "hello" );

}

}/

Вихідні дані:

Error 2

hello: No such file or directory

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]