
- •Введение
- •Глава 1. Фундаментальные концепции unix Систем
- •Программы, процессы и потоки
- •Сигналы
- •Идентификаторы процессов, группы процессов и сеансы
- •Система прав
- •Другие атрибуты процесса
- •Межпроцессное взаимодействие
- •Использование системных вызовов
- •Краткие описания функций и обработка ошибок
- •Контрольные вопросы
- •Литература
- •Глава 2. Базовые операции ввода-вывода
- •Файловые операции ввода - вывода
- •Стандартные дескрипторы
- •Системные вызовы open и creat
- •Системный вызов umask
- •Системный вызов unlink
- •Текущая позиция в файле
- •Системный вызов write
- •2.8. Системный вызов read
- •2.9. Системный вызов close
- •2.10. Системный вызов lseek
- •2.11. Системные вызовы pread и pwrite
- •2.12. Системные вызовы truncate и ftruncate
- •Контрольные вопросы
- •Литература
- •Глава 3. Дополнительные операции файлового ввода_вывода
- •Низкоуровневый доступ к файловой системе
- •Жесткие и символические ссылки
- •Системный вызов getcwd
- •Отображение метаданных файла
- •Системные вызовы getpwuid, getgrgid и getlogin
- •Каталоги
- •Системные вызовы chdir и fchdir
- •Системные вызовы mkdir и rmdir
- •Контрольные вопросы
- •Литература
- •Глава 4. Процессы и потоки
- •4.1. Среда окружения
- •Системный вызов exec
- •Системный вызов fork
- •Завершение процесса и системные вызовы exit
- •Системные вызовы wait, waitpid и waitid
- •Получение и изменение идентификаторов пользователя и группы
- •Получение и изменение приоритета
- •Контрольные вопросы
- •Литература
- •Глава 5. Механизмы межпроцессного взаимодействия
- •5.1. Каналы
- •5.2. Системные вызовы dup и dup2
- •5.3. Двунаправленное взаимодействие с использованием однонаправленных каналов
- •Контрольные вопросы
- •Литература
- •Глава 6.Механизмы взаимодействия процессов
- •Именованные каналы (fifo)
- •Системные вызовы для работы с очередями сообщений posix
- •Семафоры
- •Системные вызовы для работы с общей памятью posix
- •Контрольные вопросы
- •Литература
- •Глава 7.Сетевое взаимодействие и сокеты
- •Основные системные вызовы для работы с сокетами, образующими логические соединения
- •Обслуживание нескольких клиентов
- •Адресация сокетов
- •In_port_t sin_port; /* номер порта (uint16_t) */
- •In_addr_t s_addr; /* адрес iPv4 (uint32_t) */
- •Домен адресов af_inet6
- •In_port_t sin6_port; /* номер порта (uint16_t) */
- •Доменная система именования
- •Параметры сокетов
- •Контрольные вопросы
- •Литература
- •Глава 8.Сигналы и таймеры
- •Введение в сигналы
- •Жизненный цикл сигналов
- •Типы сигналов
- •Системный вызов sigaction
- •Контрольные вопросы
- •Литература
- •Заключение
- •Список литературы
- •Глава 2. Базовые операции ввода-вывода 14
- •Глава 3. Дополнительные операции файлового ввода_вывода 25
- •Глава 6. Механизмы взаимодействия процессов 58
2.10. Системный вызов lseek
Системный вызов lseek используется для переустановки текущей позиции в файле. Он не выполняет никаких операций ввода-вывода и не отдает команд контроллеру диска.
Lseek - устанавливает и возвращает текущую позицию в файле.
#include <unistd.h>
off_t lseek(
int fd, /* дескриптор файла */
off_t pos, /* позиция в файле */
int whence /* интерпретация аргумента pos */
);
/* Возвращает новую позицию в файле или -1 в случае ошибки (код ошибки в переменной errno) */
Аргумент whence может принимать одно из следующих значений:
SEEK_SET - аргумент pos содержит смещение от начала файла (абсолютная позиция в файле).
SEEK_CUR - аргумент pos содержит смещение от текущей позиции в файле. Может быть положительным числом, нулем и отрицательным числом. Указав в аргументе pos значение 0 - получим текущую позицию в файле.
SEEK_END - аргумент pos содержит смещение от конца файла. Может быть положительным числом, нулем и отрицательным числом. Указав в аргументе pos значение 0 - мы установим текущую позицию в конец файла.
Результатом работы вызова может быть любое неотрицательное число, даже превышающее размер файла. Если новая текущая позиция оказалась за пределами файла, ближайший вызов write вставит недостающий кусок в конец файла и заполнит его байтами со значением 0. Вызов read, с текущей позицией, установленной в конец файла или за его пределами, вернет признак конца файла - 0. Попытка чтения из интервала, который заполнил вызов write при вставке недостающего куска, увенчается успехом и в вызывающую программу будет возвращен буфер, заполненный нулями, как того и следовало ожидать. Из всех возможных вариантов вызова lseek, наиболее часто используются следующие:
для установки абсолютной позиции в файле: lseek(fd, offset, SEEK_SET);
для перемещения в конец файла: lseek(fd, 0, SEEK_END);
для получения текущей позиции в файле:
off_t where;
where = lseek(fd, 0, SEEK_CUR);
Большая часть операций по установке текущей позиции в файле выполняется ядром неявно. Так, вызов open устанавливает текущую позицию на первый байт в файле. Вызовы read и write увеличивают значение текущей позиции на количество прочитанных или записанных байт. Когда файл открывается с флагом O_APPEND, текущая позиция переустанавливается в конец файла перед каждым вызовом write.
2.11. Системные вызовы pread и pwrite
Pread - выполняет чтение из файла, начиная с заданной позиции:
#include <unistd.h>
ssize_t pread(
int fd, /* дескриптор файла*/
void *buf, /* адрес буфера для принимаемых данных*/
size_t nbytes, /* объем принимаемых данных */
off_t offset /* позиция в файле*/
);
/* Возвращает количество прочитанных байт или -1 в случае ошибки (код ошибки в переменной errno) */
Pwrite - выполняет запись в файл, в заданную позицию:
#include <unistd.h>
ssize_t pwrite(
int fd, /* дескриптор файла*/
const void *buf, /* адрес буфера с данными для записи*/
size_t nbytes, /* количество данных для записи */
off_t offset /* позиция в файле*/
);
/* Возвращает количество записанных байт или -1 в случае ошибки (код ошибки в переменной errno) */
Системные вызовы pread и pwrite по своей функциональности практически полностью совпадают с комбинацией вызова read или write соответственно, за исключением:
они не пользуются текущей позицией в файле, так как позиция для записи или чтения передается явно, через аргумент offset;
они не изменяют текущую позицию в файле. Фактически, текущая позиция полностью игнорируется этими вызовами.
Удобство применения одного вызова вместо двух неоспоримо, но, что более важно, вызовам pread и pwrite несвойственны проблемы, связанные с изменением текущей позиции в файле между lseek и последующими вызовами read или write из другого процесса или потока.