Категории
Самые читаемые
RUSBOOK.SU » Компьютеры и Интернет » Программное обеспечение » Разработка приложений в среде Linux. Второе издание - Майкл Джонсон

Разработка приложений в среде Linux. Второе издание - Майкл Джонсон

Читать онлайн Разработка приложений в среде Linux. Второе издание - Майкл Джонсон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 117 118 119 120 121 122 123 124 125 ... 150
Перейти на страницу:

3. Все ненужные файловые дескрипторы должны быть закрыты. Это может показаться очевидным, однако вы легко можете упустить закрытие тех дескрипторов, которые были унаследованы, а не открыты самой программой. Об этом речь шла в предыдущем разделе.

4. Затем программа должна вызвать fork(), а родительский процесс должен вызвать exit(), позволяя программе, запустившей демон (чаще всего командному процессору), продолжить работу.

5. Дочерний процесс, продолжающий работу, должен закрыть stdin, stdout и stderr, поскольку он не будет больше использовать терминал. Вместо повторного применения файловых дескрипторов 0, 1 и 2 лучше открывать эти файлы как /dev/null. Это гарантирует, что ни одна библиотечная функция, передающая отчеты о состоянии ошибок в stdout или stderr, не запишет эти ошибки в другие файлы, открытые демоном. При этом демон сможет запускать внешние программы, не беспокоясь об их выходных данных.

6. Для полного разъединения с терминалом, из которого был запущен демон, он должен вызвать setsid(), чтобы разместить его в собственной группе процесса. Это предотвращает получение сигналов при закрытии терминала, а также сигналов управления заданиями.

Библиотека С предлагает функцию daemon(), которая обрабатывает некоторые из перечисленных задач.

int daemon(int nochdir, in tnoclose);

Данная функция сразу осуществляет ветвление, и если оно прошло успешно, родительский процесс вызывает _exit() с кодом завершения 0. Затем дочерний процесс переходит в корневой каталог, если nochdir не является нулем, и перенаправляет stdin, stdout и stderr в /dev/null, если noclose не равен нулю. Перед возвратом в дочерний процесс она также вызывает setsid(). При этом унаследованные файловые дескрипторы все равно могут оставаться открытыми, поэтому в программах, использующих daemon(), необходимо следить за ними. Если возможно, в программе также нужно использовать chroot().

Часть IV

Библиотеки для разработки

Глава 23

Сопоставление строк

Осуществлять сравнение строк можно не только с помощью функции strcmp() или даже strncmp(). Linux предлагает несколько общих функций сопоставления строк, использование которых позволяет упростить решение задач программирования. Мы рассмотрим сначала самые простые примеры, а затем перейдем к более сложным.

23.1. Универсализация произвольных строк

В главе 14 мы говорили о том, как с помощью функции glob() производится универсализация имен файлов, однако пользователи, знакомые с возможностями универсализации, нередко пытаются применить их и к другим разновидностям строк. Функция fnmatch() позволяет применять правила универсализации в отношении произвольных строк:

#include <fnmatch.h>

int fnmatch(const char * pattern, const char * string, int flags);

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

* Соответствует любой строке, включая пустую. ? Соответствует любому одиночному символу. [ Начинает список символов для сопоставления или, если следующим символом является ^, то список символов для несовпадения. Весь список может совпадать, или не совпадать с одним символом. Список заканчивается знаком ]. Следующий символ будет интерпретироваться как литерал, а не как специальный символ.

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

FNM_NOESCAPE Обработка символа как обычного, а не специального символа. FNM_PATHNAME Символы / в строке string не сопоставляются с последовательностью *, ?, или даже [/] в шаблоне pattern; сопоставление производится только с литералом, а не специальным символом /. FNM_NOESCAPE Первый символ . в шаблоне pattern соответствует символу . в строке string только в том случае, если он является первым символом в строке string или если задано значение FNM_PATHNAME, а символ . в string непосредственно следует за символом .

Функция fnmatch() возвращает нулевое значение, если шаблон соответствует строке, FNM_NOMATCH, если шаблон не соответствует строке, или другое неопределенное значение в случае возникновения ошибки.

Пример использования функции fnmatch() вы можете посмотреть в программе, приведенной в разделе 14.7.3 главы 14, в которой эта функция используется как часть простой реализации команды find.

23.2. Регулярные выражения

Регулярные выражения, используемые в программах sed, awk, grep, vi, а также во множестве других программ Unix, со временем приобрели большое значение в среде программирования Unix. Регулярные выражения можно применять и при написании программ на языке С. В этом разделе будет рассказано об их использовании и будет предложен пример простой программы синтаксического анализа файла, построенной на этих функциях.

23.2.1. Регулярные выражения в Linux

Существуют две разновидности регулярных выражений: базовые регулярные выражения (basic regular expression — BRE) и расширенные регулярные выражения (extended regular expression — ERE). Они соответствуют (в первом приближении) командам grep и egrep. Описание каждой разновидности регулярных выражений можно найти на man-странице grep, в стандарте POSIX.2 (IEEE, 1993), в [32], а также в других источниках, поэтому здесь мы не станем описывать их синтаксис, а рассмотрим только интерфейс функции, с помощью которой вы сможете применять регулярные выражения в своих программах.

23.2.2. Сопоставление с регулярными выражениями

Стандарт POSIX определяет четыре функции обработки регулярных выражений.

#include <regex.h>

int regcomp(regex_t *preg, const char * regex, int cflags);

int regexec(const regex_t *preg, const char * string, size_t nmatch,

 regmatch_t pmatch[], int eflags);

void regfree(regex_t *preg);

size_t regerror(int errcode, const regex_t *preg, char * errbuf,

 size_t errbuf_size);

Прежде чем сравнивать строку с регулярным выражением, нужно выполнить ее компиляцию с помощью функции regcomp(). Аргумент regex_t *preg указывает на область хранения регулярного выражения. Чтобы каждое регулярное выражение было доступно одновременно, для него потребуется отдельный аргумент regex_t. Структура regex_t включает только один важный член, re_nsub, который определяет количество подвыражений в регулярном выражении, заключенных в скобки. Рассмотрим оставшуюся часть непрозрачной структуры.

Аргумент сflags определяет варианты интерпретации регулярного выражения regex. Он может иметь нулевое значение или быть любой комбинацией перечисленных ниже значений, объединенных битовым "ИЛИ".

REG_EXTENDED Вместо синтаксической структуры BRE будет использоваться структура ERE. REG_ICASE Не будет учитываться регистр. REG_NOSUB Не будут выделяться подстроки. Функция regexec() будет игнорировать аргументы nmatch и pmatch. REG_NEWLINE Если значение REG_NEWLINE не будет задано, то символ новой строки будет обрабатываться точно так же, как и любой другой символ. Символы ^ и $ соответствуют только началу и концу всей строки, а не соседним символам новой строки. Если значение REG_NEWLINE будет задано, то результат будет таким же, как и в случае использования grep, sed и других стандартных системных инструментальных средств; символ ^ осуществляет привязку к началу строки и символу, следующему после символа новой строки (фактически он соответствует строке нулевой длины, следующей за символом новой строки); $ осуществляет привязку к концу строки и символу, следующему после символа новой строки (фактически, он соответствует строке нулевой длины, предшествующей символу новой строки); символ . не соответствует символу новой строки.

Ниже представлен пример типичного вызова функции.

1 ... 117 118 119 120 121 122 123 124 125 ... 150
Перейти на страницу:
На этой странице вы можете бесплатно скачать Разработка приложений в среде Linux. Второе издание - Майкл Джонсон торрент бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Вася
Вася 24.11.2024 - 19:04
Прекрасное описание анального секса
Сергій
Сергій 25.01.2024 - 17:17
"Убийство миссис Спэнлоу" от Агаты Кристи – это великолепный детектив, который завораживает с первой страницы и держит в напряжении до последнего момента. Кристи, как всегда, мастерски строит