Читаем Linux API. Исчерпывающее руководство полностью

Если вместе с параметром — c передается простая команда (без конвейера или последовательности), некоторые командные оболочки (включая bash) для повышения эффективности вызывают команду exec напрямую, не создавая дочернего процесса. Рисунок 27.2 не совсем точно описывает оболочки, выполняющие такую оптимизацию, поскольку в их случае процессов будет два — вызывающий и команда sleep. Однако это не отменяет замечаний о том, как функция system() должна заниматься обработкой сигналов.

Все процессы, показанные на рис. 27.2, являются частью активной группы процессов в терминале (группы процессов будут подробно рассмотрены в разделе 34.2). Следовательно, если набрать в терминале последовательсть прерывания или выхода, то все процессы получат соответствующий сигнал. Сигналы SIGINT и SIGQUIT игнорируются командной оболочкой, которая ждет своих потомков, но по умолчанию приводят к завершению вызывающей программы и процесса sleep.

Каким образом вызывающий процесс и выполняемая команда должны реагировать на эти сигналы? Стандарт SUSv3 гласит следующее.

• Пока выполняется команда, сигналы SIGINT и SIGQUIT должны игнорироваться вызывающим процессом.

• Потомок должен обрабатывать сигналы SIGINT и SIGQUIT так, как это делает вызывающий процесс при использовании вызовов fork() и exec(); то есть диспозиция обрабатываемых сигналов сбрасывается к значениям по умолчанию, а диспозиции других сигналов остаются без изменений.



Рис. 27.2. Организация процессов во время выполнения system("sleep 20")


Работа с сигналами в соответствии со стандартом SUSv3 является наиболее разумным подходом, и вот почему.

• Не следует отвечать на эти сигналы сразу в двух процессах, поскольку, с точки зрения пользователя, это может привести к неожиданному поведению приложения.

• Аналогично эти сигналы нельзя игнорировать в процессе, выполняющем команду, и при этом оставлять для них диспозицию по умолчанию в вызывающем процессе. Это позволило бы пользователю, например, завершить вызывающий процесс, но оставить работать запущенную им команду. Это также идет вразрез с тем фактом, что во время выполнения команды, переданной в функцию system(), вызывающий процесс на самом деле теряет управление (то есть блокируется в вызове waitpid()).

• Команда, выполняемая функцией system(), может оказаться интерактивным приложением, и в этом случае имеет смысл позволить ей реагировать на сигналы, генерируемые терминалом.

Стандарт SUSv3 требует, чтобы сигналы SIGINT и SIGQUIT обрабатывались вышеописанным образом, но отмечает, что это может привести к нежелательным последствиям в программах, которые применяют функцию system() в фоновом режиме для выполнения некоторых задач. Нажатие Ctrl+C или Ctrl+\ во время выполнения такой команды приведет к завершению только потомка system(), тогда как само приложение продолжит работу (неожиданно для пользователя). Программа, которая использует функцию system() таким образом, должна проверять код завершения, которая та возвращает, и предпринимать соответствующие меры в случае завершения команды по сигналу.


Улучшенная реализация функции system()

В листинге 27.9 приводится реализация функции system(), отвечающая вышеописанным правилам. Обратите внимание на следующие замечания относительно этой реализации.

• Как было отмечено ранее, если в аргументе command передан нулевой указатель, функция system() должна вернуть ненулевое значение или 0 в зависимости от того, доступна командная оболочка или нет. Единственный надежный способ проверить эту информацию — это попытаться запустить командную оболочку. Для этого следует сделать рекурсивный вызов system() для выполнения встроенной команды:, которая ничего не делает, но всегда возвращает код успешного завершения; после этого нужно проверить, равняется ли полученный результат 0 . Того же результата можно было бы достичь путем запуска консольной команды exit 0. Заметьте, что для этого было бы недостаточно воспользоваться вызовом access(), чтобы проверить, существует ли файл /bin/sh и является ли он исполняемым. В среде после вызова chroot(), даже если исполняемый файл оболочки окажется на месте и он динамически скомпонован, его не получится выполнить, пока не удастся найти необходимые совместно используемые библиотеки.

• В родительском процессе (вызывающем system()) нужно блокировать только сигнал SIGCHLD , а сигналы SIGINT и SIGQUIT следует игнорировать . Однако эти действия необходимо выполнить до вызова fork(), в противном случае возникнет состояние гонки (представьте, к примеру, что потомок завершился до того, как родитель смог заблокировать SIGCHLD). Следовательно, потомок должен отменить изменения атрибутов сигнала, о чем мы поговорим чуть ниже.

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных