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

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

Жанры

Linux программирование в примерах
Шрифт:

Как

read
, так и
write
могут переместить меньше байтов, чем запрошено. Код приложения (т.е. ваш код) всегда должен учитывать это.

4.4.4. Пример: Unix

cat

Как и было обещано, вот версия cat V7 [47] . Она начинается с проверки опций,

cat
V7 принимает единственную опцию,
– u
, для осуществления небуферированного вывода.

Общая структура сходна с той, которую мы видели ранее; программа перечисляет файлы, указанные

в аргументах командной строки и читает каждый файл, по одному символу за раз, посылая этот символ в стандартный вывод. В отличие от нашей версии, она использует возможности
<stdio.h>
. Во многих случаях код, использующий стандартную библиотеку ввода/вывода, проще читать и писать, поскольку все проблемы с буферами скрыты библиотекой.

47

См.

/usr/src/cmd/cat.c
в дистрибутиве V7. Программа без изменений компилируется для GNU/Linux. — Примеч. автора.

1 /*

2 * Объединение файлов.

3 */

4

5 #include <stdio.h>

6 #include <sys/types.h>

7 #include <sys/stat.h>

8

9 char stdbuf[BUFSIZ];

10

11 main(argc, argv) /* int main(int argc, char **argv) */

12 char **argv;

13 {

14 int fflg = 0;

15 register FILE *fi;

16 register c;

17 int dev, ino = -1;

18 struct stat statb;

19

20 setbuf(stdout, stdbuf);

21 for( ; argc>1 && argv[1][0] == '-'; argc--, argv++) {

22 switch(argv[1][1]) { /* Обработка опций */

23 case 0:

24 break;

25 case 'u':

26 setbuf(stdout, (char*)NULL);

27 continue;

28 }

29 break;

30 }

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

32 statb.st_mode &= S_IFMT;

33 if (statb.st_mode != S_IFCHR && statb.st_mode != S_IPBLK) {

34 dev = statb.st_dev;

35 ino = statb.st_ino;

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
.

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

Сын Тишайшего

Яманов Александр
1. Царь Федя
Фантастика:
попаданцы
альтернативная история
фэнтези
5.20
рейтинг книги
Сын Тишайшего

"Искажающие реальность" Компиляция. Книги 1-14

Атаманов Михаил Александрович
Искажающие реальность
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
рпг
5.00
рейтинг книги
Искажающие реальность Компиляция. Книги 1-14

Школа. Первый пояс

Игнатов Михаил Павлович
2. Путь
Фантастика:
фэнтези
7.67
рейтинг книги
Школа. Первый пояс

Невеста на откуп

Белецкая Наталья
2. Невеста на откуп
Фантастика:
фэнтези
5.83
рейтинг книги
Невеста на откуп

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Аргумент барона Бронина 4

Ковальчук Олег Валентинович
4. Аргумент барона Бронина
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Аргумент барона Бронина 4

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Измена. Право на обман

Арская Арина
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на обман

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

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

Жаба с кошельком

Донцова Дарья
19. Любительница частного сыска Даша Васильева
Детективы:
иронические детективы
8.26
рейтинг книги
Жаба с кошельком

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

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

Академия чаросвет. Тень

Ярошинская Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Академия чаросвет. Тень

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4