Управління жорсткими посиланнями



Запис у файлі каталогу, що містить ім'я і номер індексного вузла, називається жорсткою посиланням. Жорстка посилання з'являється при створенні файлу будь-якого типу, включаючи каталоги. Можна створити додаткові жорсткі посилання на файли, які не є каталогами, за допомогою системного виклику link:

 

link - створює жорстку посилання # include <unistd.h>

int link (const char * oldpath, const char * newpath)

 

oldpath, старе ім'я файлу

newpath нове ім'я файлу

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

 

Перший аргумент (oldpath) повинен бути ім'ям існуючої жорсткої посилання - вона представляє номер використовуваного індексного вузла. Другий аргумент (newpath) завдає ім'я нової жорсткої посилання. Стара і нова посилання абсолютно рівноправні, так як UNIX не розрізняє первинні і вторинні посилання. Процес, який створює жорстку посилання, повинен мати право на запис у каталог, де вона розміщуватиметься. Ім'я посилання, представленої у другому аргументі, не повинно існувати - системний виклик link не вміє змінювати існуючі посилання.

У разі необхідності, існуюче посилання можна видалити викликом unlink.

Т.к. жорсткі посилання є звичайними файлами, операції вводу-виводу для них стандартні (read, write). 

 

Управління символічними посиланнями

 

Існує ще один тип посилань - символічні посилання/

На відміну від жорсткоuj посилання, символічнt посилання - новий файл особого типу, який зберігає рядок повного імені об'єкта в текстовому вигляді. Символічні посилання можуть посилатися на інші символічні посилання. Зазвичай, коли системному виклику open передається символічна посилання такого роду, ядро разименовивает їх по ланцюжку до тих пір, поки не зустріне об'єкт, який не є символічною посиланням. З жорсткими посиланнями цього не відбувається, тому що вони прямо посилаються на індексний вузол, який не може бути іншої жорсткої посиланням (хоча він може бути каталогом, який містить жорстку посилання). Іншими словами, якщо шлях до об'єкта визначається жорсткої посиланням, він може розглядатися буквально. Якщо символічної посиланням, то фактичний шлях до об'єкта залежить від вмісту проміжних символічних посилань.

Створюються символічні посилання системним викликом symlink:

 

# include <unistd.h>

int symlink (const char * oldpath, const char * newpath)

 

oldpath, можливе старе повне ім'я

newpath нове повне ім'я

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

 

Видалити символічну посилання можна за допомогою системного виклику unlink.

 

readlink - читає вміст файлу символічного посилання

 

# include <unistd.h>

ssize_t readlink (const char * path, char * buf, size_t bufsize)

 

path - повне ім'я

buf повертається текст

bufsize розмір буфера;

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

 

Системний виклик readlink повертає повне ім'я об'єкта посилання, але без завершальним символом «0», який в UNIX зазвичай служить маркером кінця рядка. Тому в якості третьої аргументу слід передавати число, на 1 менше фактичного розміру буфера, а після отримання заповненого буфера необхідно додати в нього символ «\ 0»:

 

Перейменування файлів і каталогів

 

Операція перейменування увазі зміну назви елемента каталогу. Потрібно створити нову жорстку посилання викликом link і видалити стару посилання виклику вом unlink.

Але в цьому випадку виникає ряд проблем:

  1. Файл може бути каталогом, для якого не можна створити другу жорстку посилання.
  2. Перейменований об'єкт може опинитися в іншому каталозі. Якщо це каталог тієї ж файлової системи, то проблем не виникає, але якщо інший, то виникне конфлікт, тому що link може створювати жорсткі посилання тільки в межах однієї файлової системи. Зрозуміло, можна створити символічну посилання в новому каталозі, але це не «перейменувати».
  3. Якщо необхідно «перейменувати» (фактично - «перемістити») каталог з однієї файлової системи в іншу, то доведеться перемістити ціле дерево підкаталогів з усім їхнім вмістом. Перемістити лише порожні каталоги буде недостатньо;
  4. В межах однієї файлової системи можна створити кілька жорстких посилань на один і той же файл - всі вони посилаються на один і той же індексний вузол, який не змінюється. Якщо буде необхідно перемістити файл в іншу файлову систему, то виникає наступна проблема. Створюється нова жорстка посилання, видаляється стара, але при цьому «стара» копія файлу залишиться на місці, так як файл не можна видалити, поки на нього є хоч одне посилання. Таким чином, замість «перейменування» виходить копіювання.
  5. Якщо змінити повний шлях до файлу, що міститься в символічній посиланням, то в результаті отримаємо неправильну посилання.

І т.д.

 

Тобто операція перейменування не така проста, як здається на перший погляд.

Як перейменувати каталог?

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

2. Використовувати системний виклик link для каталогів, нехай навіть виконувати його може тільки суперкористувач. - Відкинутий POSIX і замінений на rename.

3. Використовувати новий системний виклик, який буде в змозі виконувати переміщення каталогів всередині файлової системи. - Це єдиний спосіб перейменувати каталог без повного копіювання його вмісту.

 

rename - перейменовує файл «include <stdio.h>

int rename (const char * oldpath, const char * newpath)

 

oldpath, старе повне ім'я

newpath нове повне ім'я

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

 

Виклик rename виконує приблизно таку послідовність дій:

1. Якщо newpath існує, то він віддаляється за допомогою unlink або rmdir.

2. Виконується link (oldpath, newpath), навіть якщо oldpath є каталогом.

3. Викликом unlink або rmdir видаляється oldpath.

 

Крім того, він має свої особливості та обмеження.

1. Крок 2 працює і з каталогами, навіть якщо процес не має права суперкористувача (процесу достатньо мати право на запис у батьківський каталог newpath).

2. Якщо newpath існує, тоді й newpath, і oldpath повинні бути одного типу, або файли, або каталоги.

3. Якщо файл буде перенесено в новий каталог, потрібно вказати ім'я файлу в новому каталозі явно

4. Якщо newpath існує і є каталогом, він повинен бути порожній (аналогічне правило існує і у rmdir). На кроці 3, якщо oldpath - каталог, він віддаляється, навіть якщо це непорожній каталог, так як його вміст уже мається на newpath.

5. Якщо oldpath є символічною посиланням, то rename працює з нею, а не з тим, на що вона посилається.

6. Якщо rename зазнає невдачі, то все залишається без змін.

 

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

На основі системного виклику rename створена утиліта mv, яка може виконувати більш широкий діапазон дій.

− переміщати окремі файли і каталоги між файловими системами.

− переміщувати групи файлів і каталогів.

 

Індівідуальні завдання

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

2. Читати вміст зазначеного каталогу в файл. Якщо каталог порожній, видати на екран повідомлення. Ім'я каталогу вводиться з клавіатури.

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

4. Перевірити, чи є зазначений у параметрі файл каталогом. Вивести відповідну інформацію на екран. Якщо це каталог, то встановити дозвіл запису в цей каталог.

5. Вивести для певного каталогу імена текстових файлів, для яких дозволена запис. Ім'я каталогу задається через параметр командного рядка.

6. Вивести для каталогу (ім'я каталогу вводиться з клавіатури) список файлів, для яких дозволені виконання і читання.

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

8. Читати вміст зазначеного каталогу в файл. Якщо каталог не порожній, видати на екран повідомлення. Ім'я каталогу передається через параметр командного рядка.

9. Роздрукувати з поточного каталогу містять цифри імена всіх файлів з розширеннями  "*. c"   і   "*.cpp".

10. Створити в каталозі "./Links" символічні посилання на всі файли поточного каталогу з додаванням до імені файлу ".Link".

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

 


Дата добавления: 2018-04-05; просмотров: 394; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!