- •Анотація
- •1 Середовище програмування ос unix
- •1.1 Структура ос unix
- •1.2 Створення програми
- •1. Препроцесор
- •2. Транслятор
- •2.1 Компілятор
- •2.2 Асемблер
- •3. Редактор зв'язків(Компонувальником)
- •1.3 Формати об'єктних файлів
- •2 Використання файлової системи unix
- •2.1 Основні поняття
- •2.1.1 Типи та іменування файлів
- •2.1.2 Права доступу до файлів
- •2.1.3 Cистемные структури керування файлами
- •2.1.4 Системні виклики роботи з файлами
- •2.2 Створення та відкриття файлів
- •2.2.1 Системний виклик open
- •2.2.2 Системний виклик create
- •2.2.3 Системний виклик close
- •2.3 Читання та зипис в файл
- •2.3.1 Системний виклик read
- •2.3.2 Системний виклик write
- •2.4 Позіціонування у файлі
- •2.4.1 Системний виклик lseek
- •2.4.2 Системні виклики pread і pwrite
- •2.4.3 Системні виклики readv і writev
- •2.5 Контрольні операції над файлами
- •2.5.1 Системні виклики stat, fstat і lstat
- •2.5.2 Контроль прав доступу до файлу
- •2.5.3 Функція fcntl
- •2.5.4 Системні виклики truncate і ftruncate
- •2.6 Управління каталогами
- •2.6.1 Створення і видалення
- •2.6.2 Читання каталога
- •2.6.3 Зміна каталога
- •2.7 Управління посиланнями
- •2.7.1 Управління жорсткими посиланнями
- •2.7.2 Управління символічними посиланнями
- •2.7.3 Перейменування файлів і каталогів
- •3 Керування процесами ос unix
- •3.1 Процеси ос unix
- •3.2 Сисвизови створення процесів
- •3.3 Завершення процесу
- •3.4 Взаємодія процесів в ос unix
- •3.5 Сигнали
- •3.5.1 Поняття сигналу
- •3.5.2 Розробка оброблювачів сигналів
- •3.5.3 Генерація сигналів
- •3.5.4 Посилка сигналів іншим процесам
- •3.5.5 Блокування сигналів
- •3.5.6 Очікування сигналу
- •3.6 Трасування процесу.
- •3.7 Канали й fifo-Файли
- •3.7.1 Поняття
- •3.7.2 Створення каналу
- •3.7.3 Створення fifo-Файлів
- •3.8 Семафори
- •3.9 Повідомлення.
- •3.10 Поділювана пам'ять.
- •Література
- •Системне програмування Навчальний посібник
- •65082, Одеса, вул. Дворянська, 1/3
2.5 Контрольні операції над файлами
2.5.1 Системні виклики stat, fstat і lstat
У цьому розділі ми розглянемо способи отримання відомостей про файл, таких як власник, час останньої зміни і способи їх правильного відображення.
Системні виклики stat, fstat і lstat
Індексний вузол містить повний набір метаданих: про файл — все, окрім імені, яке насправді ніяк не пов'язано з індексним вузлом і даними, на які він указує. Процедура читання даних з індексного вузла прямо з файлу пристрою є дуже низькорівневою. На щастя, для отримання інформації з індексних вузлів, існують три стандартні системні виклики — stat, lstat і fstat і одна дуже відома команда — ls.
stat — повертає відомості про файл по його імені
«include <sys/stat.h>
int stat(const char *path, struct stat *buf )
path - повне ім'я файлу
struct stat *buf - структура, що зберігає значення індексного дескриптора файлу
Повертає 0 у разі успіху -1 у разі помилки (код помилки -в змінної errno)
lstat — повертає відомості про файл по його імені без разыменования символічних посилань
«include <sys/stat.h>
int lstat(const char*path, struct stat *buf);
path - повне ім'я файлу
struct stat *buf - повертана інформація
Повертає 0 у разі успіху -1 у разі помилки (код помилки - в змінній errno) */
fstat — повертає відомості про файл по дескриптору
#include <sys/stat.h>
int fstat(const int fd, struct stat *buf);
fd - дескриптор файлу
struct stat *buf - повертана інформація
Повертає 0 у разі успіху -1 у разі помилки (код помилки - в змінній errno)
Системний виклик stat приймає повне ім'я файлу і знаходить відповідний йому індексний вузол. Виклик fstat приймає дескриптор відкритого файлу і відшукує відповідний індексний вузол в таблиці активних вузлів ядра. Виклик lstat аналогічний виклику stat за одним виключенням — якщо як ім'я файлу було передано символічне посилання, то буде повернена інформація про саме посилання, а не про об'єкт, який вона представляет*. Всі три виклики повертають одні і ті ж метадані, через структуру типу stat, в першому аргументі.
Нижче приводиться визначення структури stat. Проте в деяких реалізаціях поля структури можуть бути переставлені місцями, можуть бути додані нові поля
struct stat — структура для прийому відомостей з stat, fstat і lstat
struct stat {
dev_t st_dev; ідентифікатор пристрою
ino_t st_ino; номер індексного вузла
mode_t st_mode; режими доступу, тип
nlink_t st_nlink; к-ть жорстких посилань
uid_t st_uid; ідентифікатор користувача
gid_t st_gid; ідентифікатор групи
dev_t st_rdev; ідентифікатор пристрою
/* (для спеціального файлу) */
off_t st_size; розмір в байтах
time_t st_atime; час останнього звернення
time_t st_mtime; час останньої зміни
time_t st_ctime; час останньої зміни
blksize_t st_blksize; оптимальний розмір блоку
(для операцій введення-виводу)
blkcnt_t st_blocks; (к-ть блоків по 512 байт)
}
Деякі зауваження по цій структурі.
Ідентифікатор пристрою (типу dev_t) — це число, унікальне для кожної змонтованої файлової системи, навіть для NFS-томов. Таким чином, комбінації st_dev і st_ino однозначно ідентифікують будь-який індексний вузол в системі.— власне пристрій. Як правило, молодший номер пристрою — це самий молодший байт.
Поле st.dev — це пристрій, на якому знаходиться індексний вузол. Поле st_rdev використовується тільки для спеціальних файлів пристроїв і є пристроєм, який спеціальний файл представляє.
Поле st_size інтерпретується залежно від типу файлу і реалізації. Для звичайних файлів, каталогів і символічних посилань — це об'єм даних на диску (для символічних посилань — довжина шляху). Для об'єктів в пам'яті, що розділяється, — об'єм займаної пам'яті. Для каналів — кількість даних в каналі.
Поле st_blksize призначене для зміни розміру блоку файлу. В більшості випадків, ймовірно, має те ж призначення, що і аналогічне поле в суперблоці.
Якщо файл має «дірки», отримані як результат установки поточної позиції у файлі за його межі і подальшому записі яких-небудь даних, значення st_blocks * 512 може опинитися менше значення st_size.
Системний виклик fstat особливо затребуваний в ситуаціях, коли потрібно отримати відомості про елемент, що не має шляху у файловій системі, наприклад, про неіменований канал або сокет. Для цих об'єктів поля st_mode, st_ino, st_dev, st_uid, st_gid, st_atime, st_ctime і st_mtime містять актуальні значення, але що стосується інших полів — все залежить від реалізації. Проте, для іменованих і неіменованих каналів поле st_size, як правило, містить кількість непрочитаних байт в каналі.
Поле st_ctime Час останньої зміни індексного вузла (st_ctime) іноді називається як «час останньої зміни статуса».изменяется (встановлюється рівним поточному астрономічному часу) при застосуванні до файлу викликів creat, chmod, chown, link, unlink, mknod, utime*, write (оскільки змінюється довжина файлу); не оновлюється при читанні даних з файлу. Це поле слід розглядати як час модифікації прав доступу до файлу;
st_mtime - write, creat, mknod, utime; Це поле слід розглядати як час модифікації вмісту файлу (даних);
st_atime - read, creat, mknod, utime; Це поле слід розглядати як час читання вмісту файлу (даних).
Визначення типу файлу
Поле st_mode містить 12 битий, що визначають тип файлу і права доступу. Макрос S_IFMT — це маска всіх бітів, які відносяться до типу файлу в полі st_mode.
Операція st_mode файлу & S_IFMT повертає значення типу:
S_IFREG - звичайний файл
S_IFDIR - каталог
S_IFBLK - спеціальний файл блокового пристрою
S_IFCHR - спеціальний файл символьного пристрою
S_IFIFO - іменований або неіменований канал
S_IFLNK - символічне посилання
S_IFSOCK - сокет
struct stat sbuf;
...
if(stat(file &sbuf) == 0)
if((sbuf.st_mode & S_IFMT) == S_IFDIR)
printf(“A directory\n”);
if ((buf.st_mode & S_IFSOCK) == S_IFSOCK) /*невірно*/
Треба так:
if ((buf.st_mode & S_IFMT) == S_IFSOCK)
UNIX містить ряд макросів для визначення типу файлу. Вони визначаються в <sys/stat.h> and <linux/stat.h>:
S_ISREG() regular file
S_ISDIR() directory file
S_ISCHR() char. special file
S_ISBLK() block special file
S_ISFIFO() pipe or FIFO
S_ISLNK() symbolic link
S_ISSOCK() socket
Перевірка — чи є файл сокетом, за допомогою макросу може бути виконана так:
if (S_ISSOCK(buf.st_mode))
Визначення прав доступу до файлу
Для визначення прав доступу в полі st_mode є 9 битий. Імена цих макросів слідують формі запису: s_Ipwww, де символ p — режим доступу (R, w або X), а www — кому видано право на цей режим доступу (USR, GRP або OTH).
S_Ixwww де x = R|W|X, www = USR|GRP|OTH
приклади:
S_IRUSR
S_IWOTH
S_ISUID set-user-id bit is set
S_ISGID set-group-id bit is set
S_ISVTX sticky bit is set
Цими макросами є бітові маски.
1) Тоді перевірка прав на читання і на запис для групи буде такий:
if ((buf.st_mode &(S_IRGRP|S_IWGRP))= (S_IRGRP|S_IWGRP))
2) перевірка установки біта зміни ідентифікатора користувача
if((sbuf.st_mode & S_ISUID) != 0)
printf(“set-user-id bit is set\n”);
Приклад використання
Напишіть програму, що друкує інформацію про всі відкриті нею файли і канали. Для цієї мети використовуйте системний виклик
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/param.h>
#include <sys/fcntl.h>
main
{
struct stat st;
int fd;
open(“file”,O_RDONLY);
for(fd=0; fd < NOFILE; fd++ )
if (fstat(fd &st ==0)
{
printf("File stats\n");
printf(" File size: %ld\n", st.st_size);
printf(" Permission: %o\n", st.st_mode & 0x01ff);
/* шістнадцятиричне число = 0001 1111 1111
Можна так
stat( имяФайла &st);
коды Доступа = st.st_mode & 0777;
або S_IRWXU| S_IRWXG| S_IRWXO */
printf(" Owner uid: %d\n", st.st_uid);
printf(" Owner gid: %d\n", st.st_gid);
printf("\n");
}
}
}
Програма може використовувати дескриптори файлів з номерами 0..NOFILE-1 (зазвичай 0..19). Якщо fstat для якогось fd повернув код помилки (<0), це означає, що даний дескриптор не пов'язаний з відкритим файлом (тобто не використовується). NOFILE визначене в include-файле <sys/param.h>, що містить різноманітні параметри даної системи.
По відкритому файлу не існує простого способу дізнатися його ім'я. Для цього треба сисвызовом fstat дізнатися номер пристрою і номер індексного дескриптора, після чого знайти у файловій системі відповідний запис.