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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

36 }

37 if (argc < 2) {

38 argc = 2;

39 fflg++;

40 }

41 while (--argc > 0) { // Loop over files

42 if (fflg || (*++argv)[0] == '-' && (*argv)[1] == '\0')

43 fi = stdin;

44 else {

45 if ((fi = fopen(*argv, "r")) == NULL) {

46 fprintf(stderr, "cat: can't open %s\n", *argv);

47 continue;

48 }

49 }

50 fstat(fileno(fi), &statb); /*
Строки 50-56 объясняются в главе 5 */

51 if (statb.st_dev == dev && statb.st_ino == ino) {

52 fprintf(stderr, "cat: input %s is output\n",

53 fflg ? "-" : *argv);

54 fclose(fi);

55 continue;

56 }

57 while ((c=getc(fi)) != EOF) /* Копировать содержимое в stdout */

58 putchar(с);

59 if (fi != stdin)

60 fclose(fi);

61 }

62 return(0);

63 }

Следует заметить, что программа всегда завершается успешно (строка 62); можно было написать ее так, чтобы отмечать ошибки и указывать их в возвращаемом значении

main
. (Механизм завершения процесса и значение различных кодов завершения обсуждаются в разделе 9.1.5.1 «Определение статуса завершения процесса».)

Код, работающий с

struct stat
и функцией
fstat
(строки 31–36 и 50–56), без сомнения, непрозрачен, поскольку мы еще не рассматривали эти функции и не будем рассматривать до следующей главы (Но обратите внимание на использование
fileno
в строке 50 для получения нижележащего дескриптора файла, связанного с переменными
FILE*
.) Идея в основе этого кода заключается в том, чтобы убедиться, что входной и выходной файлы не совпадают. Это предназначено для предотвращения бесконечного роста файла, в случае подобной команды:

$ cat myfile >> myfile /* Добавить копию myfile к себе? */

И конечно же, проверка работает:

$ echo hi > myfile /* Создать файл */

$ v7cat myfile >> myfile /* Попытка добавить файл к себе */

cat: input myfile is output

Если вы попробуете это с

ch04-cat
, программа продолжит работу, и
myfile
будет расти до тех пор, пока вы не прервете ее. GNU версия
cat
осуществляет эту проверку. Обратите внимание, что что-то вроде этого выходит за рамки контроля
cat
:

$ v7cat < myfile > myfile

cat: input - is output

$ ls -l myfile

– rw-r--r-- 1 arnold devel 0 Mar 24 14:17 myfile

В данном случае это слишком поздно, поскольку оболочка урезала файл

myfile
(посредством
оператора
>
) еще до того, как
cat
получила возможность исследовать файл! В разделе 5.4.4.2 «Возвращаясь к V7 cat» мы объясним код с
struct stat
.

4.5. Произвольный доступ: перемещения внутри файла

До сих пор мы обсуждали последовательный ввод/вывод, при котором данные читаются или записываются с начала файла и продолжаются до его конца. Часто это все, что требуется программе. Однако, возможно осуществление произвольного ввода/вывода; т.е. читать данные из произвольного положения в файле без необходимости предварительного чтения всего, что находится перед этим местом.

Смещение дескриптора файла является положением внутри открытого файла, начиная с которого будет осуществляться следующая операция чтения или записи. Программа устанавливает смещение с помощью системного вызова

lseek
:

#include <sys/types.h> /* для off_t; POSIX */

#include <unistd.h> /* объявления lseek и значений whence */

off_t lseek(int fd, off_t offset, int whence);

Тип

off_t
(тип смещения) является знаковым целым, представляющим позиции байтов (смещений от начала) внутри файла. На 32-разрядных системах тип представлен обычно как
long
. Однако, многие современные системы допускают очень большие файлы, в этом случае
off_t
может быть более необычным типом, таким, как C99
int64_t
или какой-нибудь другой расширенный тип.
lseek
принимает три следующих аргумента.

int fd

Дескриптор открытого файла.

off_t offset

Позиция, в которую нужно переместиться. Интерпретация этого значения зависит от параметра

whence
.
offset
может быть положительным или отрицательным; отрицательные значения перемещают к началу файла; положительные значения перемещают к концу файла.

int whence

Описывает положение в файле, относительно которого отсчитывается

offset
. См. табл. 4.4.

Таблица 4.4. Значения

whence
для
lseek

Именованная константа Значение Комментарий
SEEK_SET
0
offset
абсолютно, т.е. относительно начала файла
SEEK_CUR
1
offset
относительно текущей позиции в файле
SEEK_END
2
offset
относительно конца файла.
Поделиться:
Популярные книги

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

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

Я Гордый Часть 3

Машуков Тимур
3. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый Часть 3

Агенты ВКС

Вайс Александр
3. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Агенты ВКС

Блуждающие огни

Панченко Андрей Алексеевич
1. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Блуждающие огни

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Архил...?

Кожевников Павел
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...?

Глава рода

Шелег Дмитрий Витальевич
5. Живой лёд
Фантастика:
боевая фантастика
6.55
рейтинг книги
Глава рода

Мастер 11

Чащин Валерий
11. Мастер
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер 11

Звездная Кровь. Изгой V

Елисеев Алексей Станиславович
5. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
технофэнтези
рпг
фантастика: прочее
5.00
рейтинг книги
Звездная Кровь. Изгой V

Эпоха Опустошителя. Том I

Павлов Вел
1. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том I

Заточи свой клинок и Вперед!

Шиленко Сергей
1. Заточи свой клинок, и Вперед!
Фантастика:
юмористическая фантастика
рпг
попаданцы
5.00
рейтинг книги
Заточи свой клинок и Вперед!

Я все еще не князь. Книга XV

Дрейк Сириус
15. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я все еще не князь. Книга XV

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Локки 11. Потомок бога

Решетов Евгений Валерьевич
11. Локки
Фантастика:
героическая фантастика
боевая фантастика
фэнтези
юмористическое фэнтези
5.00
рейтинг книги
Локки 11. Потомок бога