Выбрать главу

• WAIT_OBJECT_0+n, где 0 ≤ n < nCount — вычтите значение WAIT_OBJECT_0 из возвращенного значения, чтобы определить, выполнение какого именно процесса завершилось, когда ожидается завершение выполнения любого из группы процессов. Если в сигнальное состояние перешли несколько объектов, то возвращается наименьшее из возможных значений. WAIT_ABANDONED является возможным базовым значением в случае использования дескрипторов мьютексов; см. главу 8.

• WAIT_TIMEOUT — указывает на то, что в течение отведенного периода ожидания сигнализируемый объект (объекты) не смогли удовлетворить условию ожидания.

• WAIT_FAILED — означает неудачное завершение функции, вызванное, например, тем, что у дескриптора отсутствовали права доступа SYNCHRONIZE.

• WAIT_ABANDONED_0 — это значение невозможно в случае процессов и рассматривается в главе 8 при рассмотрении мьютексов.

Для определения кода завершения процесса используется функция GetExitCodeProcess, описанная в предыдущем разделе.

Блоки и строки окружения

Схема, представленная на рис. 6.1, включает блок окружения процесса. Блок окружения (environment block) процесса содержит последовательность строк вида:

Имя = Значение

Каждая строка окружения (environment string), будучи символьной строкой, заканчивается нулевым символом, а весь блок строк в целом завершается дополнительным нулевым символом. Одним из примеров широко используемых переменных среды является переменная PATH. 

Чтобы передать информацию об окружении из родительского процесса в дочерний, параметр lpEnvironment при вызове функции CreateProcess следует установить равным NULL. В свою очередь, любой процесс может запросить или изменить свои переменные окружения или добавить новые в блок окружения.

Для получения, а также создания новых или изменения существующих переменных окружения используются следующие функции: 

DWORD GetEnvironmentVariable(LPCTSTR lpName, LPTSTR lpValue, DWORD cchValue)

BOOL SetEnvironmentVariable(LPCTSTR lpName, LPCTSTR lpValue) 

lpName — указатель на строку, содержащую имя переменной окружения. После определения переменной окружения она добавляется в блок окружения при условии, что такая переменная ранее не существовала, а определяемое значение не равно NULL. Если же определяемое значение равно NULL, то переменная удаляется из блока. Строка значения не может содержать символы "=".

В случае успешного завершения функция GetEnvironmentVariable возвращает длину строки значения переменной окружения, иначе — 0. Если размер буфера lpValue, указанный значением параметра cchValue, оказался недостаточно большим, то возвращаемое значение равно количеству символов, которое фактически требуется для сохранения значения переменной. Вспомните, что аналогичный механизм используется и в функции GetCurrentDirectory (глава 2).

Защита процесса

Обычно функция CreateProcess предоставляет права доступа к процессу на уровне PROCESS_ALL_ACCESS. Однако имеется возможность определения детализированных прав доступа, из которых в качестве примера можно назвать права доступа PROCESS_QUERY_INFORMATION, CREATE_PROCESS, PROCESS_TERMINATE, PROCESS_SET_INFORMATION, DUPLICATE_HANDLE и CREATETHREAD. В частности, с учетом возможных рисков, которые могут подстерегать вас в случае принудительного завершения выполняющихся процессов, на что мы уже неоднократно обращали ваше внимание, может оказаться полезным ограничить предоставление прав доступа к процессам на уровне PROCESS_TERMINATE для родительского процесса. Подробнее об атрибутах защиты процессов и других объектов говорится в главе 15. 

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

Строки окружения, аналогичные строкам окружения Windows, поддерживаются и в UNIX. Функция getenv (входящая в библиотеку С) имеет те же самые функциональные возможности, что и функция GetEnvironmentVariable, но программист сам должен заботиться о необходимом размере буфера. Функции putenv, setenv и unsetenv обеспечивают различные способы добавления, изменения и удаления переменных окружения и их значений, предлагая функциональность, аналогичную функциональности SetEnvironmentVariable.