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

3. Додаткові функції маніпулювання даними індексних дескрипторів

Перевірка прав доступу до файлу

access (filename, mode)

char * filename;

int mode;

Функція access перевіряє, чи має процес дозвіл на читання, запис або виконання файлу Якщо pathname є символьним посиланням, то перевіряються права доступу до файлу, на який вона вказує. mode - це маска, що складається з одного або більше прапорів R_OK, W_OK, X_OK і F_OK.

R_OK, W_OK і X_OK використовуються для перевірки, чи існує файл і чи можна його читати, записувати в нього або виконувати, F_OK просто перевіряє наявність файлу.

Повертає 0 у разі успіху, -1 у випадку помилки (код помилки-у змінній errno)

Зміна власника файлу

chown - зміна власника та групи файлу

СИНТАКСИС

int chown (path, owner, group)

char * path;

int owner, group;

ОПИС

Аргумент path є покажчиком на маршрутне ім'я файлу. Ідентифікатори власника та групи зазначеного файлу встановлюються рівними числовим значенням, відповідно, аргументів owner і group.

Тільки root може змінити власника файлу. Власник файлу може змінювати групу файлу на будь-яку групу, до якої він належить. Root може довільно проводити цю заміну.

Зміна прав доступу до файлу

chmod - зміна режиму доступу до файлу

# Include <sys/types.h>

# include <sys/stat.h>

int chmod (const char * path, mode_t mode);

int fchmod (int fildes, mode_t mode);

Можна змінювати коди доступу, відповідні бітової масці

0777 | S_ISUID | S_ISGID | S_ISVTX

Аргумент path є покажчиком на маршрутне ім'я файлу. Системний виклик chmod встановлює режим доступу до вказаного файлу відповідно до бітним шаблоном, що містяться в аргументі mode.

Змінювати права доступу до файлу може тільки процес, що має чинний ідентифікатор користувача, рівний ідентифікатору власника файлу або суперкористувача.

Якщо системні виклики chown і chmod виконуються не суперкористувачем, то біти перевстановлення ідентифікаторів користувача і групи, 04000 і 02000 відповідно, обнуляються.

Зміна системної маски прав доступу

Ми вже згадували про маску, що накладається на набір прав доступу при створенні файлу. Накладення маски виконує системний виклик umask, який рідко використовується де-небудь ще, крім як в команді umask.

Umask - встановлює і повертає маску прав доступу для знову создава ваних файлів.

# Include <sys/stat.h>

mode_t umask (mode_t cmask);

cmask - нова маска

Повертає попереднє значення маски повернення кодів помилок не передбачений

Так як кожен процес має маску і будь-яка комбінація з 9 біт вважається припустимою, umask не передбачає вихід помилково. Він завжди повертає колишнє значення маски. Щоб дізнатися поточне значення маски не змінюючи її, потрібно виконати дві послідовних виклику umask. Перший - щоб отримати поточне значення маски (передавши у виклик будь-яке значення нової маски), другий - щоб відновити її в первісний стан.

4. Отримання даних про відкриті файли

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

#include <fcntl.h>

int fcntl (int fd, int cmd, arg)

Функція виконує команду cmd над дескриптором файлу fd.

Деякі команди вимагають завдання додаткових аргументів.

Таблиця 3

Основні команди cmd

F_DUPFD

Дублювання дескриптора файлу. Повертає інший дескриптор, що асоціюється з тим же відкритим файлом;

F_GETFD

Отримує прапори, що асоціюються з дескриптором;

F_SETFD

Встановлює прапори, що асоціюються з дескриптором;

F_GETFL

Отримує прапори, що асоціюються з відкритим файлом;

F_SETFL

Встановлює прапори, що асоціюються з відкритим файлом;

F_GETLK

Отримує інформацію про захоплені області файлу;

F_SETLK

Встановлює або скидає захоплення файлу;

F_SETLKW

Ідентично F_SETLK, але чекає закінчення виконання;

F_GETOWN

Отримує процес або групу процесів, яким буде посланий сигнал SIGIO

F_SETOWN

Встановлює процес або групу процесів, яким буде посланий сигнал SIGIO

Діагностика

При успішному завершенні системного виклику залежно від операції cmd повертаються наступні значення:

F_DUPFD Новий дескриптор файлу.

F_GETFD Значення прапора (визначений тільки молодший біт).

F_SETFD Значення, відмінне від -1.

F_GETFL Значення прапорів статусу файлу.

F_SETFL Значення, відмінне від -1.

F_GETLK Значення, відмінне від -1.

F_SETLK Значення, відмінне від -1.

F_SETLKW Значення, відмінне від -1.

У разі помилки повертається -1, а змінною errno привласнюється код помилки.

Отримання і установка прапора стану файлу

1) Як по дескриптору файлу дізнатися, відкритий він на читання, запис, читання і запис одночасно?

int flags;

if((flags=fcntl (fd, F_GETFL, NULL)) < 0 )

return NULL; /* fd ймовірно не відкритий */

flags &= O_RDONLY | O_WRONLY | O_RDWR;

switch(flags){

case O_RDONLY: return "r";

case O_WRONLY: return "w";

case O_RDWR: return "r+w";

default: return NULL;

}

2) приклад зміни прапора дескриптора:

int flags = fcntl (fd, F_GETFL, 0);

fcntl (fd, F_SETFL, flags | O_NONBLOCK);

3) установка нового власника

fcntl(fd, F_SETOWN, getpid())

4) setflag (int desc, int value)

{

int oldflags = fcntl (desc, F_GETFL, 0);

/* якщо відбулася помилка, виходимо з програми */

if (oldflags == -1)

return -1;

/* встановлюємо тільки потрібний прапор */

if (value != 0)

oldflags |= O_NONBLOCK;

else

oldflags &= ~O_NONBLOCK;

/* зберігаємо прапор в дескрипторі файлу */

return fcntl (desc, F_SETFL, oldflags);

}

Передається два параметри: дескриптор і індикатор – 0, якщо треба зняти прапор і не 0, якщо встановити.

|= додає ?=~ знімає ~ інвертує

Зберігаємо в дескрипторі, повертаємо в зухвалу процедуру.

Блокування файлів з використанням fcntl

Окрім модифікації файлового дескриптора системний виклик fcntl(2) використовується для блокування файлу. Блокування областей файлу дозволяє декільком програмам спільно працювати з вмістом одного і того ж файлу, не заважаючи один одному.

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

В цьому випадку cmd - тип блокуючої операції, а в у arg указується адреса структури flock, в яку записується інформація про блокування. Структура і відповідні макроси описані в заголовному файлі <fcntl.h>.

Таблиця 4

Опис полий структури flock

Поле

Значення

short l_type

Тип блокування: записи – F_RDLCK, читання – F_WRLCK, скидання – F_UNLCK.

short l_whence

Адреса початку ділянки, що блокується; дається у вигляді зсуву відносно початку файлу (0), щодо поточної позиції покажчика (1), щодо кінця файлу (2)

Продовження таблиці 4

Поле

Значення

long l_start

Зсув в байтах, що інтерпретується відповідно до значення l_whence

long l_len

Довжина ділянки, що блокується, в байтах. Якщо вказаний 0, блокується ділянка від l_start до кінця файлу

long l_pid

Ідентифікатор процесу, що встановив блокування (для GETLCK)

long l_sysid

Ссистемний ідентифікатор процесу, блокуючого файл

Якщо задана область вже заблокована, fcntl повертає -1.

За допомогою команди F_GETLK можна дізнатися, ідентифікатор процесу, що заблокував дану область.

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

За допомогою цієї функції можна маніпулювати дескрипторами файлів і встановлювати рекомендаційні (advisory) блокування (необов'язкові). В цьому випадку, якщо програма сама не використовує блокувань, блокування, встановлені іншими програмами, не матимуть для неї ніякого ефекту. Існує можливість додати рекомендаційним блокуванням fcntl() обов'язковий характер, але для цього відповідна файлова система повинна бути змонтована із спеціальним ключем.

Базові правила використання блокувань:

  • Програми, які хочуть читати з файлу, належний відкрити файл, а потім використовувати fcntl в режимі F_RDLCK

  • Програми, які хочуть читати з файлу і записувати у файл повинні відкрити файл, а потім використовувати flock в режимі F_WRLCK.

  • Виклик flock блокуватиме файл до тих пір, поки він доступний, в цей час необхідні операції можуть бути виконані з деякою мірою безпеки.

  • Після виконання операцій приберіть блокування шляхом закриття файлового дескриптора або за допомогою F_UNLCK

Приклад

1. Для установки блокування ми заповнюємо поля структури flock необхідними значеннями і викликаємо fcntl() з командою F_SETLK (встановити блокування):

..

struct flock fi;

fd=open(file, O_RDWR);

fi.l_type = F_WRLCK;

fi.l_whence = SEEK_SET;

fi.l_start = 0;

fi.l_len = 64;

off = 0;

while (fcntl(fd, F_SETLK &fi)== -1)

{ fcntl(fd, F_GETLK & fi);

...

printf("байти %i - %i заблоковані процесом %i\n", off, off+64

fi.l_pid);

}

Якщо задана область вже заблокована, fcntl повертає -1. За допомогою команди F_GETLK можна дізнатися, ідентифікатор процесу, що заблокував дану область.

2. Для того, щоб зняти блокування, ми викликаємо fctnl() з командою F_SETLK (дивно, чи не так?) і параметром l_type = F_UNLCK:

fi.l_type = F_UNLCK;

if (fcntl(fd, F_SETLK &fi)== -1)

printf("Помилка разблокирования\n");

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