Функции _spawn, _wspawn
Каждая из функций _spawn создает и выполняет новый процесс:
Буквы в конце имени функции определяют вариант функции.
e
envp — массив указателей на параметры среды — передается в новый процесс.l
Аргументы командной строки передаются по отдельности в функцию _spawn. Данный суффикс обычно используется, если несколько параметров в новом процессе известны заранее.p
Переменная среды PATH используется, чтобы найти файл для выполнения.v
argv — массив указателей на аргументы командной строки — передается в функцию _spawn. Данный суффикс обычно используется, если число параметров в новом процессе может изменяться.
Заметки
Каждая из функций _spawn создает и выполняет новый процесс. Они автоматически обрабатывают аргументы в виде многобайтовых строк как подходящие, распознавая многобайтовые последовательности символов в соответствии с текущей многобайтовой кодовой страницей. Функции _wspawn являются версиями _spawn, работающими с расширенными символами; они не обрабатывают строки многобайтовых символов. В противном случае функции _wspawn ведут себя идентично соответствующим функциям _spawn.
Универсальное текстовое сопоставление функций
Подпрограмма Tchar.h |
_UNICODE и _MBCS не определены |
_MBCS определено |
_UNICODE определено |
---|---|---|---|
_tspawnl |
_spawnl |
_spawnl |
_wspawnl |
_tspawnle |
_spawnle |
_spawnle |
_wspawnle |
_tspawnlp |
_spawnlp |
_spawnlp |
_wspawnlp |
_tspawnlpe |
_spawnlpe |
_spawnlpe |
_wspawnlpe |
_tspawnv |
_spawnv |
_spawnv |
_wspawnv |
_tspawnve |
_spawnve |
_spawnve |
_wspawnve |
_tspawnvp |
_spawnvp |
_spawnvp |
_wspawnvp |
_tspawnvpe |
_spawnvpe |
_spawnvpe |
_wspawnvpe |
Должно быть доступно достаточно памяти для загрузки и выполнения нового процесса. Аргумент mode определяет действие, предпринимаемое процессом перед и в течение _spawn. Следующие значения mode определены в Process.h:
_P_OVERLAY
Перекрывает вызывающий процесс новым процессом, уничтожающим вызывающий процесс (тот же эффект, что и у вызова _exec)._P_WAIT
Приостанавливает вызывающий поток до тех пор, пока выполнение нового процесса не будет закончено (синхронный _spawn)._P_NOWAIT или _P_NOWAITO
Вызывающий процесс продолжает выполняться одновременно с новым процессом (асинхронный _spawn)._P_DETACH
Вызывающий процесс продолжает выполняться; новый процесс выполняется в фоновом режиме без доступа к консоли или клавиатуре. Вызовы _cwait для нового процесса завершились ошибкой (асинхронное _spawn).
Аргумент cmdname задает файл, который выполняется как новый процесс, можно указать полный путь (от корневой папки), частичный путь (от текущей рабочей папки), или только имя файла. Если cmdname не имеет расширения имени файла или не заканчивается точкой (.), функция _spawn сначала пытается использовать расширение .com, затем расширение .exe, расширение .bat и, наконец, расширение .cmd.
Если cmdname имеет расширение имени файла, используется только это расширение. Если cmdname заканчивается точкой, вызов _spawn ищет cmdname без расширения имени файла. Функции _spawnlp, _spawnlpe, _spawnvp и _spawnvpe ищут cmdname (используя те же процедуры) в каталогах, указанных в переменной среды PATH.
Если cmdname содержит спецификатор диска или любые символы косой черты (то есть, если это относительный путь), то вызов _spawn ищет указанный файл; поиск пути не выполняется.
В прошлом некоторые из этих функций устанавливали errno в ноль в случае успеха; сейчас errno остается нетронутым в случае успеха в соответствии со стандартом C. Если требуется эмулировать старое поведение, задайте errno в ноль непосредственно перед вызовом этих функций.
Примечание
Для обеспечения правильной инициализации перекрывания и завершения перекрывания не используйте функцию setjmp или longjmp для входа в перекрывающую процедуру или выхода из нее.
Аргументы для порожденного процесса
Для передачи аргументов в новый процесс укажите один или несколько указателей на символьные строки в качестве аргументов при вызове _spawn. Эти символьные строке формируют список аргументов для порожденного процесса. Совмещенная длина строк, формирующих список аргументов для нового процесса, не должна превышать 1024 байта. Завершающий нулевой символ ('\0') для каждой строки не включается в длину, но пробелы (автоматически добавленные для отделения аргументов) включены.
Примечание
Пробелы в строках могут вызвать неожиданное поведение; например, передача _spawn строки "hi there" приведет к получению новым процессом двух аргументов, "hi" и "there".Если целью было заставить новый процесс открыть файл с именем "hi there", процесс завершится с ошибкой.Чтобы избежать этого можно заключить строку в кавычки: "\"hi there\"".
![]() |
---|
Не передавайте введенные пользователем данные в _spawn без явной проверки их содержимого._spawn приведет к вызову CreateProcess, поэтому имейте в виду, что неквалифицированные пути могут привести к потенциальным уязвимостям безопасности. |
Можно передавать указатели аргументов как отдельные аргументы (в _spawnl, _spawnle, _spawnlp и _spawnlpe) или как массив указателей (в _spawnv, _spawnve, _spawnvp и _spawnvpe). Необходимо передать по крайней мере один аргумент arg0 или argv[0] порождаемому процессу. По соглашению, этот аргумент является именем программы, как если бы вы вводили его в командной строке. Другое значение не вызывает ошибку.
Вызовы _spawnl, _spawnle, _spawnlp и _spawnlpe обычно используются в случаях, когда число аргументов известно заранее. Аргумент arg0 обычно является указателем на cmdname. Аргументы от arg1 до argn являются указателями на символьные строки, формируя новый список аргументов. После argn должно следовать указатель NULL, отмечающий конец списка аргументов.
Вызовы _spawnv, _spawnve, _spawnvp и _spawnvpe полезны при переменном числе аргументов для нового процесса. Указатели на аргументы передаются как массив argv*.* Аргумент argv[0] обычно является указателем на путь в реальном режиме или на название программы в защищенном режиме, а argv[1] по argv[n] — указатели на символьные строки, формирующие новый список аргументов. Аргумент argv[n +1] должен быть указателем NULL, отмечающим конец списка аргументов.
Среда порожденного процесса
Файлы, открытые на момент вызова _spawn, остаются открытыми в новом процессе. В вызовах _spawnl, _spawnlp, _spawnv и _spawnvp новый процесс наследует среду вызывающего процесса. Можно использовать вызовы _spawnle, _spawnlpe, _spawnve и _spawnvpe для изменения среды нового процесса путем передачи списка параметров среды с помощью аргумента envp. Аргумент envp является массивом указателей на символы, каждый элемент которого (кроме последнего элемента) указывает на завершенную нулевым символом строку, определяющую переменную среды. Такая строка обычно имеет форму NAME=value, где NAME — имя переменной среды, а value — строковое значение, которое эта переменная принимает. (Обратите внимание, что value не заключается в двойные кавычки). Последний элемент массива envp должен быть NULL. Если envp само NULL, порожденный процесс наследует параметры среды родительского процесса.
Функции _spawn могут передавать все сведения об открытых файлах, в том числе режим преобразования, в новый процесс. Эти сведения передаются в обычном режиме через запись C_FILE_INFO среды. Код запуска обычно обрабатывает эту запись и затем удаляет ее из среды. Однако если функция _spawn порождает не С процесс, эта запись остается в среде. Вывод среды показывает графические символы в строке определения для этой записи, поскольку данные среды передаются в бинарной форме в обычном режиме. Это не должно влиять на обычные операции. В защищенном режиме информация о среде передается в текстовой форме и поэтому не содержит символы графики.
Необходимо явным образом сохранить (с помощью fflush или _flushall) или закрыть любой поток до вызова функции _spawn.
Новые процессы, созданные вызовами процедур _spawn, не сохраняют параметры сигнала. Вместо этого порожденные процессы сбрасывают параметры сигналов на значения по умолчанию.
Перенаправление вывода
Если вы вызываете _spawn из библиотеки DLL или приложения с графическим интерфейсом пользователя и хотите перенаправить выходные данные в каналу, имеется два варианта:
Использовать Win32 API для создания канала, а затем вызвать AllocConsole, задать значения дескриптора в структуре запуска и вызвать CreateProcess.
Вызвать _popen, _wpopen, что создаст канал, и запустить приложение с использованием cmd.exe /c (или command.exe /c).
Пример
// crt_spawn.c
// This program accepts a number in the range
// 1-8 from the command line. Based on the number it receives,
// it executes one of the eight different procedures that
// spawn the process named child. For some of these procedures,
// the CHILD.EXE file must be in the same directory; for
// others, it only has to be in the same path.
//
#include <stdio.h>
#include <process.h>
char *my_env[] =
{
"THIS=environment will be",
"PASSED=to child.exe by the",
"_SPAWNLE=and",
"_SPAWNLPE=and",
"_SPAWNVE=and",
"_SPAWNVPE=functions",
NULL
};
int main( int argc, char *argv[] )
{
char *args[4];
// Set up parameters to be sent:
args[0] = "child";
args[1] = "spawn??";
args[2] = "two";
args[3] = NULL;
if (argc <= 2)
{
printf( "SYNTAX: SPAWN <1-8> <childprogram>\n" );
exit( 1 );
}
switch (argv[1][0]) // Based on first letter of argument
{
case '1':
_spawnl( _P_WAIT, argv[2], argv[2], "_spawnl", "two", NULL );
break;
case '2':
_spawnle( _P_WAIT, argv[2], argv[2], "_spawnle", "two",
NULL, my_env );
break;
case '3':
_spawnlp( _P_WAIT, argv[2], argv[2], "_spawnlp", "two", NULL );
break;
case '4':
_spawnlpe( _P_WAIT, argv[2], argv[2], "_spawnlpe", "two",
NULL, my_env );
break;
case '5':
_spawnv( _P_OVERLAY, argv[2], args );
break;
case '6':
_spawnve( _P_OVERLAY, argv[2], args, my_env );
break;
case '7':
_spawnvp( _P_OVERLAY, argv[2], args );
break;
case '8':
_spawnvpe( _P_OVERLAY, argv[2], args, my_env );
break;
default:
printf( "SYNTAX: SPAWN <1-8> <childprogram>\n" );
exit( 1 );
}
printf( "from SPAWN!\n" );
}