Friday, May 18th

Last update12:13:00 PM GMT

Вы находитесь на: FreeBSD Службы ядра Обработка результатов

Обработка результатов

В конечном счете системный вызов возвращается в вызывающий процесс либо успешно, либо неудачно. На архитектуре PC успех или неудача возвращаются в виде бита переноса в слове состояния программы пользовательского процесса: если он равен нулю, возвращение было успешным; в противном случае возвращение безуспешно. На многих машинах возвращаемые значения функций C передаются через регистр общего назначения (для PC регистр данных ЕАХ). Процедуры в ядре, которые реализуют системные вызовы, возвращают значения, которые обычно связаны с глобальной переменной errno. После системного вызова обработчик системного вызова ядра оставляет это значение в регистре. Если системный вызов завершился неудачей, библиотечная процедура C помещает это значение в errno и устанавливает в возвращаемом регистре значение -1. Ожидается, что вызывающий процесс заметит значение в возвращаемом регистре и проверит errno. Механизм, включающий бит переноса и глобальную переменную errno, существует по историческим причинам, ведя начало от PDP-11.

Есть две разновидности неудачного возвращения из системного вызова: те, когда процедуры ядра обнаруживают ошибку, и те, когда системный вызов прерывается. Наиболее обычным случаем является прерывание системного вызова, когда он уступил процессор в ожидании события, которое может не возникать в течение длительного времени (такого, как ввод с терминала), и в этот промежуток поступает сигнал. Когда обработчики сигнала инициализированы процессом, они указывают, должны ли прерванные ими системные вызовы запускаться повторно, или они должны возвратить ошибку прерванного системного вызова (EINTR).

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

Повторный запуск системного вызова путем установки счетчика команд имеет некоторые последствия. Во-первых, ядро не должно изменять какие-либо входные параметры в адресном пространстве процесса (оно может изменить копию параметров в ядре, которые оно делает). Во-вторых, оно должно убедиться, что системный вызов не совершил каких-нибудь действий, которые нельзя повторить. Например, в текущей системе, если с терминала были прочитаны какие-либо символы, результат чтения должен возвращаться с коротким числом. В противном случае, если вызов должен был быть запущен снова, уже прочитанные байты были бы потеряны.

Сейчас 56 гостей онлайн

Реклама на сайте: