Linux программирование в примерах
Linux программирование в примерах читать книгу онлайн
В книге рассмотрены вопросы, связанные с программированием под Linux: файловый ввод/вывод, метаданные файлов, основы управления памятью, процессы и сигналы, пользователи и группы, вопросы интернационализации и локализации, сортировка, поиск и многие другие. Много внимания уделено средствам отладки, доступным под GNU Linux. Все темы иллюстрируются примерами кода, взятого из V7 UNIX и GNU. Эта книга может быть полезна любому, кто интересуется программированием под Linux.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
47 целиком в буфер. Увеличить буфер и попытаться снова. */
48 if (p[-1] != 'n')
49 goto more_buffer;
50
51 /* Мы получили новую строку, увеличить число строк. */
52 ++nlines;
Строки 43–52 увеличивают указатель на участок буфера за только что прочитанными данными. Затем код проверяет, является ли последний прочитанный символ символом конца строки. Конструкция
p[-1]
p[0]
p[1]
*(p-1)
Если последний символ не был символом конца строки, это означает, что нам не хватило места, и код выходит (с помощью
goto
54 #if !defined(WINDOWS32) && !defined(__MSDOS__)
55 /* Проверить, что строка завершилась CRLF; если так,
56 игнорировать CR. */
57 if ((p - start) > 1 && p[-2] == 'r')
58 {
59 --p;
60 p[-1] = 'n';
61 }
62 #endif
Строки 54–62 обрабатывают вводимые строки, следующие соглашению Microsoft по завершению строк комбинацией символов возврата каретки и перевода строки (CR-LF), а не просто символом перевода строки (новой строки), который является соглашением Linux/Unix. Обратите внимание, что
#ifdef
<stdio.h>
64 backslash = 0;
65 for (p2 = p - 2; p2 >= start; --p2)
66 {
67 if (*p2 != '\')
68 break;
69 backslash = !backslash;
70 }
71
72 if (!backslash)
73 {
74 p[-1] = ' ';
75 break;
76 }
77
78 /* Это была комбинация обратный слеш/новая строка. Если есть
79 место, прочесть еще одну строку. */
80 if (end - p >= 80)
81 continue;
82
83 /* В конце буфера нужно больше места, поэтому выделить еще.
84 Позаботиться о сохранении текущего смещения в p. */
85 more_buffer:
86 {
87 unsigned long off = p - start;
88 ebuf->size *= 2;
89 start = ebuf->buffer=ebuf->bufstart=(char*)xrealloc(start,
90 ebuf->size);
91 p = start + off;
92 end = start + ebuf->size;
93 *p = ' ';
94 }
95 }
До сих пор мы имели дело с механизмом получения в буфер по крайней мере одной полной строки. Следующий участок обрабатывает случай строки с продолжением. Хотя он должен гарантировать, что конечный символ обратного слеша не является частью нескольких обратных слешей в конце строки. Код проверяет, является ли общее число таких символов четным или нечетным путем простого переключения переменной
backslash
Если число четное, условие '
!backshlash
С другой стороны, если число нечетно, строка содержит четное число пар обратных слешей (представляющих символы \, как в С), и конечную комбинацию символов обратного слеша и конца строки. [43] В этом случае, если в буфере остались по крайней мере 80 свободных байтов, программа продолжает чтение в цикле следующей строки (строки 78–81). (Использование магического числа 80 не очень здорово; было бы лучше определить и использовать макроподстановку.)
По достижении строки 83 программе нужно больше места в буфере. Именно здесь вступает в игру динамическое управление памятью. Обратите внимание на комментарий относительно сохранения значения
p
Обратите внимание, что здесь вызывается функция
xrealloc()
malloc()
realloc()
NULL
extern const char *myname; /* установлено в main() */
void *xrealloc(void *ptr, size_t amount) {
void *p = realloc(ptr, amount);
if (p == NULL) {
fprintf(stderr, "%s: out of memory!n", myname);
exit(1);
}
return p;
}
Таким образом, если функция
xrealloc()
ptr = xrealloc(ptr, new_size)