- •Анотація
- •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.4.2 Системні виклики pread і pwrite
pread — виконує читання з файлу, починаючи із заданої позиції
#include <unistd.h>
#include <sys/types.h>
ssize_t pread( int fd, void *buf, size_t nbytes,
off_t offset)
fd - дескриптор файлу
*buf адреса буфера для даних, що приймаються
nbytes - об'єм даних, що приймаються
offset - позиція у файлі;
Повертає кількість прочитаних байт або -1 у разі помилки (код помилки - в змінній errno)
pwrite — виконує запис у файл, в задану позицію
#include <unistd.h>
#include <sys/types.h>
ssize_t pwrite(int fd, void *buf, size_t nbytes, off_t offset)
fd - дескриптор файлу
*buf - адреса буфера з даними для запису
nbytes - кількість даних для запису
offset - позиція у файлі
Повертає кількість записаних байт або -1 у разі помилки (код помилки - в змінній errno)
Системні виклики pread і pwrite по своїй функціональності практично повністю співпадають з комбінацією виклику lseek і подальшим викликом read або write відповідно, за виключенням:
вони не користуються поточною позицією у файлі, оскільки позиція для запису або читання передається явно, через аргумент offset;
вони не змінюють поточну позицію у файлі. Фактично, поточна позиція повністю ігнорується цими викликами.
Для файлів, відкритих з прапором O_APPEND (див. розділ 2.8), поведінка pwrite повністю співпадає з поведінкою виклику write (аргумент offset ігнорується).
Зручність застосування одного виклику замість двох незаперечно, але, що важливіше, викликам pread і pwrite невластиві проблеми, пов'язані із зміною поточній позиції у файлі між lseek і подальшими викликами read або write з іншого процесу або потоку. Це може відбутися при використанні одного дескриптора декількома потоками додатку або при використанні дублікатів дескрипторів декількома процесами. То ж відноситься і до файлів, відкритих з прапором O_APPEND. Оскільки ні pread, ні pwrite не використовують покажчик поточної позиції у файлі, їм невластиві помилки пов'язані з невірним позиціонуванням.
2.4.3 Системні виклики readv і writev
readv — читання урозкид
#include <sys/uio.h>
#include <sys/types.h>
ssize_t readv(int fd, const struct iovec *iov,int iovcnt );
fd - дескриптор файлу
*iov - масив буферів для даних, що приймаються
iovcnt - кількість буферів
Повертає кількість прочитаних байт або -1 у разі помилки (код помилки - в змінній errno)
writev — запис із злиттям
#include <sys/uio.h>
#include <sys/types.h>
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
fd - дескриптор файлу
*iov - масив буферів з даними
iovcnt - кількість буферів
Повертає кількість записаних байт або -1 у разі помилки (код помилки - в змінній errno)
Виклики readv і writev дуже схожі на виклики read і write, але на відміну від останніх мають справу не з одним, а з декількома буферами. Іноді їх називають «читання урозкид» і «запис із злиттям». У файлі дані як і раніше розташовуються підряд, один за одним, але буфери можуть бути розкидані в пам'яті процесу.
Іншими словами, якщо вам необхідно записати у файл три структури, то замість трьох викликів write це можна зробити одним викликом writev, проте, поглянувши па другий аргумент, ви без зусиль зрозумієте — щоб використовувати ці виклики, доведеться трохи потрудитися, але чи коштують вони наших зусиль?
Перед викликом будь-якій з цих функцій, ви повинні створити масив iov (елементів iovcnt), в якому кожен елемент містить покажчик на буфер з даними і розмір буфера, по суті — другий і третій аргументи викликів read і write.
struct iovec — структура, використовувана в системних викликах rcadv і writev*
struct iovec {
void *iov_base; /* адреса буфера з даними */
size_t iov_len; /* розмір буфера */
}
У своїх програмах ви можете оголосити статичний масив з struct iovec а також розмістити його в динамічній пам'яті викликом malloc або іншим способом. Максимальне число елементів масиву для різних OС може декілька відрізнятися, але воно ніколи не буває менше 16. У OСL, що задовольняють специфікації SUS, ідентифікатор IOV_MAX відповідає максимальному числу елементів масиву. Якщо цей ідентифікатор не визначений, можна скористатися функцією sysconf з аргументом _.SC_IOV_MAX Але в більшості: реальних застосувань 16 елементів більш ніж достатньо.