Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
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
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
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
, который определяет количество подвыражений в регулярном выражении, заключенных в скобки. Рассмотрим оставшуюся часть непрозрачной структуры.
Интервал:
Закладка: