Чтение онлайн

на главную - закладки

Жанры

UNIX — универсальная среда программирования
Шрифт:

 exit(0);

}

error
мы обсудим ниже.

Число файлов, которые одновременно могут быть открыты программой, ограничено (обычно порядка 20; см.

NOFILE
в
<SYS/param.h>
). Поэтому любая программа, которой предстоит обрабатывать много файлов, должна быть готова неоднократно использовать одни и те же дескрипторы файлов. Системный вызов
close
разрывает связь между именем и дескриптором файла, освобождая дескриптор для использования с некоторым другим файлом. Завершение программы посредством
exit
и возврат из основной программы закрывают все открытые файлы. Вызов системы unlink удаляет файл из файловой системы.

Обработка ошибок:
errno

Обсуждаемые здесь системные вызовы, а по сути все системные вызовы, могут вызывать ошибки. Обычно они сигнализируют об ошибке, возвращая значение -1. Иногда полезно знать, какая именно ошибка произошла, поэтому системные вызовы, когда это приемлемо, оставляют номер ошибки во внешней целой переменной, называемой

errno
. (Значение различных номеров ошибок объясняется во введении к разд. 2 справочного руководства по UNIX.) С помощью
errno
ваша программа может определить, например, чем вызвана неудача при открытии файла — тем, что он не существует, или тем, что у вас нет разрешения на его чтение. Кроме того, есть массив символьных строк
sys_errlist
, индексируемый
errno
, который переводит число в строку, передающую смысл ошибки. Наша версия error использует эти структуры данных:

error(s1, s2) /* print error message and die */

 char *s1, *s2;

{

 extern int errno, sys_nerr;

 extern char *sys_errlist[], *progname;

 if (progname)

fprintf(stderr, "%s: ", progname);

 fprintf(stderr, s1, s2);

 if (errno > 0 && errno < sys_nerr)

fprintf (stderr, " (%s)", sys_errlist[errno]);

 fprintf(stderr, "\n");

 exit(1);

}

Errno
первоначально равна нулю и всегда должна быть меньше, чем
sys_herr.
Она не становится нулевой вновь при нормальной работе, поэтому вы должны обнулять ее после каждой ошибки, если ваша программа будет продолжать выполняться. Сообщения об ошибках в нашей версии
cp
появляются следующим образом:

$ cp foo bar

cp: can't open foo
(Нет такого файла или каталога)

$ date >foo; chmod 0 foo
Создать нечитаемый файл

$ cp too bar

cp: can't open foo
(В разрешении отказано)

$

Произвольный доступ:
lseek

Файл ввода-вывода обычно последовательный: каждый

read
или
write
занимает место в файле непосредственно после использованного при предыдущем вызове. Однако при необходимости файл может быть прочитан или записан в произвольном порядке. Системный вызов
lseek
позволяет перемещаться по файлу, не осуществляя ни чтения, ни записи:

int fd, origin;

long offset, pos, lseek;

pos = lseek(fd, offset, origin);

Текущая

позиция в файле с дескриптором
fd
перемещается к позиции
offset
, которая отсчитывается относительно места, определяемого
origin
. Последующие процессы чтения или записи будут начинаться с этой позиции.
Origin
может иметь значения 0, 1, 2, задавая тем самым начало отсчета значения
offset
 — от начала, от текущей позиции или от конца файла соответственно.

Возвращаемое значение есть новая абсолютная позиция или -1 при ошибке. Например, при добавлении информации в файл нужно дойти до его конца, а затем выполнить запись:

lseek(fd, 0L, 2);

Чтобы вернуться обратно к началу ("перемотать"), необходимо вызвать

lseek(fd, 0L, 0);

Для определения текущей позиции следует выполнить

pos = lseek(fd, 0L, 1);

Обратите внимание на аргумент

0L
: смещение есть длинное целое. ('l' в lseek означает 'long' — длинный, чтобы отличить его от системного вызова
seek
в шестой версии, где используются короткие целые.)

С помощью

lseek
можно обращаться с файлами как с большими массивами, однако при этом время доступа к ним возрастает. Например, следующая функция читает любое число байтов из любого места в файле:

get(fd, pos, buf, n) /* read n bytes from position pos */

 int fd, n;

 long pos;

 char *buf;

{

 if (lseek(fd, pos, 0) == -1) /* get to pos */

return -1;

 return read(fd, buf, n);

}

Упражнение 7.3

Модифицируйте

readslow
так, чтобы обрабатывать имя файла в качестве аргумента, если оно присутствует. Добавьте
– е
:

$ readslow -е

заставляет

readslow
искать конец входного потока, прежде чем начать чтение. Каковы функции
lseek
при работе с программным каналом?

Упражнение 7.4

Перепишите

efopen
из гл. 6, чтобы вызвать error.

7.2 Файловая система: каталоги

Наша следующая тема — как ориентироваться в иерархии каталогов. При этом мы будем использовать не новые системные вызовы, а лишь несколько старых в новом контексте. В качестве примера приведем функцию

spname
, которая пытается справиться с неверно написанными именами файлов. Функция

n = spname(name, newname);

ищет файл с именем, "достаточно близким" к name. Если такое имя найдено, оно копируется в

newname
. Значение n, возвращаемое
spname
, равно -1, если ничего достаточно близкого не найдено, 0 — при точном совпадении и 1, если была сделана коррекция.

Поделиться:
Популярные книги

Император Пограничья 1

Астахов Евгений Евгеньевич
1. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 1

Пушкарь. Пенталогия

Корчевский Юрий Григорьевич
Фантастика:
альтернативная история
8.11
рейтинг книги
Пушкарь. Пенталогия

Бастард

Осадчук Алексей Витальевич
1. Последняя жизнь
Фантастика:
фэнтези
героическая фантастика
попаданцы
5.86
рейтинг книги
Бастард

Кодекс Крови. Книга ХII

Борзых М.
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Крови. Книга ХII

#Бояръ-Аниме. Газлайтер. Том 36

Володин Григорий Григорьевич
36. История Телепата
Фантастика:
боевая фантастика
аниме
фэнтези
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 36

Кодекс Охотника. Книга XXXII

Винокуров Юрий
32. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXXII

Академия

Щепетнов Евгений Владимирович
3. Петр Синельников
Фантастика:
фэнтези
6.20
рейтинг книги
Академия

Хозяин Теней

Петров Максим Николаевич
1. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней

Гамбургский счет: Статьи – воспоминания – эссе (1914–1933)

Шкловский Виктор Борисович
Научно-образовательная:
история
5.00
рейтинг книги
Гамбургский счет: Статьи – воспоминания – эссе (1914–1933)

Имперец. Том 1 и Том 2

Романов Михаил Яковлевич
1. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 1 и Том 2

Громовая поступь. Трилогия

Мазуров Дмитрий
Громовая поступь
Фантастика:
фэнтези
рпг
4.50
рейтинг книги
Громовая поступь. Трилогия

Ведун

Сухов Александр Евгеньевич
1. Второй шанс
Фантастика:
фэнтези
боевая фантастика
альтернативная история
5.00
рейтинг книги
Ведун

Бастард Императора. Том 8

Орлов Андрей Юрьевич
8. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 8

Офицер

Земляной Андрей Борисович
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Офицер