Книга: Linux программирование в примерах
5.4.4.2. Возвращаясь к V7 cat
5.4.4.2. Возвращаясь к V7 cat
В разделе 4.4.4 «Пример: Unix cat» мы обещали вернуться к программе V7 cat
, чтобы посмотреть, как она использует системный вызов stat()
. Первая группа строк, использовавшая ее, была такой:
31 fstat(fileno(stdout), &statb);
32 statb.st_mode &= S_IFMT;
33 if (statb.st_mode != S_IFCHR && statb.st_mode != S_IFBLK) {
34 dev = statb.st_dev;
35 ino = statb.st_ino;
36 }
Этот код теперь должен иметь смысл. В строке 31 вызывается fstat()
для стандартного вывода, чтобы заполнить структуру statb
. Строка 32 отбрасывает всю информацию в statb.st_mode
за исключением типа файла, используя логическое AND с маской S_IFMT
. Строка 33 проверяет, что используемый для стандартного вывода файл не является файлом устройства. В таком случае программа сохраняет номера устройства и индекса в dev
и ino
. Эти значения затем проверяются для каждого входного файла в строках 50–56.
50 fstat(fileno(fi), &statb);
51 if (statb.st_dev == dev && statb.st_ino == ino) {
52 fprintf(stderr, "cat: input %s is outputn",
53 ffig ? "-" : *argv);
54 fclose(fi);
55 continue;
56 }
Если значения st_dev
и st_ino
входного файла совпадают с соответствующими значениями выходного файла, cat
выдает сообщение и продолжает со следующего файла, указанного в командной строке.
Проверка сделана безусловно, хотя dev
и ino
устанавливаются, лишь если вывод не является файлом устройства. Это срабатывает нормально из-за того, как эти переменные объявлены:
int dev, ino = -1;
Поскольку ino
инициализирован значением (-1), ни один действительный номер индекса не будет ему соответствовать[60]. То, что dev
не инициализирован так, является небрежным, но не представляет проблемы, поскольку тест в строке 51 требует, чтобы были равными значения как устройства, так и индекса. (Хороший компилятор выдаст предупреждение, что dev
используется без инициализации: 'gcc -Wall
' сделает это.)
Обратите также внимание, что ни один вызов fstat()
не проверяется на ошибки. Это также небрежность, хотя не такая большая, маловероятно, что fstat()
завершится неудачей с действительным дескриптором файла
Проверка того, что входной файл не равен выходному файлу, осуществляется лишь для файлов, не являющихся устройствами. Это дает возможность использовать cat
для копирования ввода из файлов устройств в самих себя, как в случае с терминалами:
$ tty /* Вывести имя устройства текущего терминала */
/dev/pts/3
$ cat /dev/pts/3 > /dev/pts/3 /* Копировать ввод от клавиатуры на экран */
this is a line of text /* Набираемое в строке */
this is a line of text /* cat это повторяет */
- Dedications
- Compiling the user-land applications
- Integrated Secure Communications System
- 4. MODIFICATIONS
- 1. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- 3. Hexadecimal – the way we communicate with micros
- The Impossibility of Communication
- CHAPTER 6 Productivity Applications
- Available Applications
- Productivity Applications Written for Microsoft Windows
- Using the Amanda Backup Application
- File System Authentication and Access Control